<commit_before># Copyright 2016, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools 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.
#
# SETools 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 SETools.  If not, see
# <http://www.gnu.org/licenses/>.
#
import logging
import copy

from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QDialog, QFrame, QWidget

from ..models import SEToolsListModel
from ..widget import SEToolsWidget

class PermissionMapEditor(SEToolsWidget, QDialog):

    """
    A permission map editor.  This dialog has two versions,
    one for editing the weight/direction and another for
    including or excluding permissions in an analysis.

    Parameters:
    parent      The parent Qt widget
    edit        (bool) If true, the dialog will take
                the editor behavior.  If False, the dialog
                will take the enable/disable permission
                behavior.
    """

    class_toggle = pyqtSignal(bool)

    def __init__(self, parent, edit):
        super(PermissionMapEditor, self).__init__(parent)
        self.log = logging.getLogger(__name__)
        self.parent = parent
        self.edit = edit
        self.setupUi()

    def setupUi(self):
        self.load_ui("permmap_editor.ui")

        # set up class list
        self.class_model = SEToolsListModel(self)
        self.classes.setModel(self.class_model)

        # permission widgets
        self.widgets = []

        # set up editor mode
        self.enable_all.setHidden(self.edit)
        self.disable_all.setHidden(self.edit)

        # connect signals
        self.classes.selectionModel().selectionChanged.connect(self.class_selected)
        self.enable_all.clicked.connect(self.enable_all_perms)
        self.disable_all.clicked.connect(self.disable_all_perms)

    def show(self, perm_map):
        # keep an internal copy because the map is mutable
        # and this dialog may be canceled after some edits.
        self.perm_map = copy.deepcopy(perm_map)

        self.class_model.item_list = sorted(perm_map.classes())

        # clear class selection and mappings
        # since this widget will typically
        # be reused.
        self.classes.clearSelection()
        self._clear_mappings()
        self.enable_all.setToolTip(None)
        self.disable_all.setToolTip(None)

        if self.edit:
            self.setWindowTitle("{0} - Permission Map Editor - apol".format(self.perm_map))
        else:
            self.setWindowTitle("{0} - Permission Map Viewer - apol".format(self.perm_map))

        super(PermissionMapEditor, self).show()

    def accept(self):
        self.parent.apply_permmap(self.perm_map)
        super(PermissionMapEditor, self).accept()

    def class_selected(self):
        # the .ui is set to 1 selection
        for index in self.classes.selectionModel().selectedIndexes():
            class_name = self.class_model.data(index, Qt.DisplayRole)

        self.log.debug("Setting class to {0}".format(class_name))

        self.enable_all.setToolTip("Include all permissions in the {0} class.".format(class_name))
        self.disable_all.setToolTip("Exclude all permissions in the {0} class.".format(class_name))

        self._clear_mappings()

        # populate new mappings
        for perm in sorted(self.perm_map.perms(class_name)):
            # create permission mapping
            mapping = PermissionMapping(self, perm, self.edit)
            mapping.setAttribute(Qt.WA_DeleteOnClose)
            self.class_toggle.connect(mapping.enabled.setChecked)
            self.perm_mappings.addWidget(mapping)
            self.widgets.append(mapping)

            # add horizonal line
            line = QFrame(self)
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)
            self.perm_mappings.addWidget(line)
            self.widgets.append(line)

    def enable_all_perms(self):
        self.class_toggle.emit(True)

    def disable_all_perms(self):
        self.class_toggle.emit(False)

    #
    # Internal functions
    #
    def _clear_mappings(self):
        # delete current mappings
        for mapping in self.widgets:
            mapping.close()

        self.widgets.clear()

index_to_setting = ["r", "w", "b", "n"]
index_to_word = ["Read", "Write", "Both", "None"]
setting_to_index = {"r": 0, "w": 1, "b": 2, "n": 3}

class PermissionMapping(SEToolsWidget, QWidget):

    """
    A widget representing mapping for a particular permission.
    This dialog has two versions, one for editing the weight/direction
    and another for including or excluding permissions in an analysis.

    Parameters:
    parent      The parent Qt widget
    edit        (bool) If true, the widget will take
                the editor behavior.  If False, the dialog
                will take the enable/disable permission
                behavior.
    """

    def __init__(self, parent, mapping, edit):
        super(PermissionMapping, self).__init__(parent)
        self.log = logging.getLogger(__name__)
        self.parent = parent
        self.mapping = mapping
        self.edit = edit
        self.setupUi()

    def setupUi(self):
        self.load_ui("permmapping.ui")

        self.permission.setText(str(self.mapping.perm))
        self.weight.setValue(self.mapping.weight)
        self.enabled.setChecked(self.mapping.enabled)

        if self.edit:
            self.weight.setToolTip("Set the information flow weight of {0}".format(
                self.mapping.perm))
            self.direction.setToolTip("Set the information flow direction of {0}".format(
                self.mapping.perm))
        else:
            self.enabled.setToolTip("Include or exclude {0} from the analysis.".format(
                self.mapping.perm))

        self.weight.setEnabled(self.edit)
        self.direction.setEnabled(self.edit)
        self.enabled.setHidden(self.edit)

        # setup color palettes for direction
        self.orig_palette = self.direction.palette()
        self.error_palette = self.direction.palette()
        self.error_palette.setColor(QPalette.Button, Qt.red)
        self.error_palette.setColor(QPalette.ButtonText, Qt.white)

        # setup direction
        self.direction.insertItems(0, index_to_word)
        if self.mapping.direction == 'u':
            # Temporarily add unmapped value to items
            self.direction.insertItem(len(index_to_word), "Unmapped")
            self.direction.setCurrentText("Unmapped")
            self.direction.setPalette(self.error_palette)
            self.unmapped = True
        else:
            self.direction.setCurrentIndex(setting_to_index[self.mapping.direction])
            self.unmapped = False

        # connect signals
        self.direction.currentIndexChanged.connect(self.set_direction)
        self.weight.valueChanged.connect(self.set_weight)
        self.enabled.toggled.connect(self.set_enabled)

    def set_direction(self, value):
        if self.unmapped:
            if value == "Unmapped":
                return

            # Remove unmapped item if setting the mapping.
            self.direction.removeItem(len(index_to_word))
            self.direction.setPalette(self.orig_palette)
            self.unmapped = False

        dir_ = index_to_setting[value]
        self.log.debug("Setting {0.class_}:{0.perm} direction to {1}".format(self.mapping, dir_))
        self.mapping.direction = dir_

    def set_weight(self, value):
        self.log.debug("Setting {0.class_}:{0.perm} weight to {1}".format(self.mapping, value))
        self.mapping.weight = int(value)

    def set_enabled(self, value):
        self.log.debug("Setting {0.class_}:{0.perm} enabled to {1}".format(self.mapping, value))
        self.mapping.enabled = value
<commit_msg>PermissionMapEditor: Python 2.7 fix<commit_after># Copyright 2016, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools 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.
#
# SETools 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 SETools.  If not, see
# <http://www.gnu.org/licenses/>.
#
import logging
import copy

from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QDialog, QFrame, QWidget

from ..models import SEToolsListModel
from ..widget import SEToolsWidget

class PermissionMapEditor(SEToolsWidget, QDialog):

    """
    A permission map editor.  This dialog has two versions,
    one for editing the weight/direction and another for
    including or excluding permissions in an analysis.

    Parameters:
    parent      The parent Qt widget
    edit        (bool) If true, the dialog will take
                the editor behavior.  If False, the dialog
                will take the enable/disable permission
                behavior.
    """

    class_toggle = pyqtSignal(bool)

    def __init__(self, parent, edit):
        super(PermissionMapEditor, self).__init__(parent)
        self.log = logging.getLogger(__name__)
        self.parent = parent
        self.edit = edit
        self.setupUi()

    def setupUi(self):
        self.load_ui("permmap_editor.ui")

        # set up class list
        self.class_model = SEToolsListModel(self)
        self.classes.setModel(self.class_model)

        # permission widgets
        self.widgets = []

        # set up editor mode
        self.enable_all.setHidden(self.edit)
        self.disable_all.setHidden(self.edit)

        # connect signals
        self.classes.selectionModel().selectionChanged.connect(self.class_selected)
        self.enable_all.clicked.connect(self.enable_all_perms)
        self.disable_all.clicked.connect(self.disable_all_perms)

    def show(self, perm_map):
        # keep an internal copy because the map is mutable
        # and this dialog may be canceled after some edits.
        self.perm_map = copy.deepcopy(perm_map)

        self.class_model.item_list = sorted(perm_map.classes())

        # clear class selection and mappings
        # since this widget will typically
        # be reused.
        self.classes.clearSelection()
        self._clear_mappings()
        self.enable_all.setToolTip(None)
        self.disable_all.setToolTip(None)

        if self.edit:
            self.setWindowTitle("{0} - Permission Map Editor - apol".format(self.perm_map))
        else:
            self.setWindowTitle("{0} - Permission Map Viewer - apol".format(self.perm_map))

        super(PermissionMapEditor, self).show()

    def accept(self):
        self.parent.apply_permmap(self.perm_map)
        super(PermissionMapEditor, self).accept()

    def class_selected(self):
        # the .ui is set to 1 selection
        for index in self.classes.selectionModel().selectedIndexes():
            class_name = self.class_model.data(index, Qt.DisplayRole)

        self.log.debug("Setting class to {0}".format(class_name))

        self.enable_all.setToolTip("Include all permissions in the {0} class.".format(class_name))
        self.disable_all.setToolTip("Exclude all permissions in the {0} class.".format(class_name))

        self._clear_mappings()

        # populate new mappings
        for perm in sorted(self.perm_map.perms(class_name)):
            # create permission mapping
            mapping = PermissionMapping(self, perm, self.edit)
            mapping.setAttribute(Qt.WA_DeleteOnClose)
            self.class_toggle.connect(mapping.enabled.setChecked)
            self.perm_mappings.addWidget(mapping)
            self.widgets.append(mapping)

            # add horizonal line
            line = QFrame(self)
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)
            self.perm_mappings.addWidget(line)
            self.widgets.append(line)

    def enable_all_perms(self):
        self.class_toggle.emit(True)

    def disable_all_perms(self):
        self.class_toggle.emit(False)

    #
    # Internal functions
    #
    def _clear_mappings(self):
        # delete current mappings
        for mapping in self.widgets:
            mapping.close()

        # in Python3 a .clear() function was added for lists
        # keep this implementation for Python 2 compat
        del self.widgets[:]

index_to_setting = ["r", "w", "b", "n"]
index_to_word = ["Read", "Write", "Both", "None"]
setting_to_index = {"r": 0, "w": 1, "b": 2, "n": 3}

class PermissionMapping(SEToolsWidget, QWidget):

    """
    A widget representing mapping for a particular permission.
    This dialog has two versions, one for editing the weight/direction
    and another for including or excluding permissions in an analysis.

    Parameters:
    parent      The parent Qt widget
    edit        (bool) If true, the widget will take
                the editor behavior.  If False, the dialog
                will take the enable/disable permission
                behavior.
    """

    def __init__(self, parent, mapping, edit):
        super(PermissionMapping, self).__init__(parent)
        self.log = logging.getLogger(__name__)
        self.parent = parent
        self.mapping = mapping
        self.edit = edit
        self.setupUi()

    def setupUi(self):
        self.load_ui("permmapping.ui")

        self.permission.setText(str(self.mapping.perm))
        self.weight.setValue(self.mapping.weight)
        self.enabled.setChecked(self.mapping.enabled)

        if self.edit:
            self.weight.setToolTip("Set the information flow weight of {0}".format(
                self.mapping.perm))
            self.direction.setToolTip("Set the information flow direction of {0}".format(
                self.mapping.perm))
        else:
            self.enabled.setToolTip("Include or exclude {0} from the analysis.".format(
                self.mapping.perm))

        self.weight.setEnabled(self.edit)
        self.direction.setEnabled(self.edit)
        self.enabled.setHidden(self.edit)

        # setup color palettes for direction
        self.orig_palette = self.direction.palette()
        self.error_palette = self.direction.palette()
        self.error_palette.setColor(QPalette.Button, Qt.red)
        self.error_palette.setColor(QPalette.ButtonText, Qt.white)

        # setup direction
        self.direction.insertItems(0, index_to_word)
        if self.mapping.direction == 'u':
            # Temporarily add unmapped value to items
            self.direction.insertItem(len(index_to_word), "Unmapped")
            self.direction.setCurrentText("Unmapped")
            self.direction.setPalette(self.error_palette)
            self.unmapped = True
        else:
            self.direction.setCurrentIndex(setting_to_index[self.mapping.direction])
            self.unmapped = False

        # connect signals
        self.direction.currentIndexChanged.connect(self.set_direction)
        self.weight.valueChanged.connect(self.set_weight)
        self.enabled.toggled.connect(self.set_enabled)

    def set_direction(self, value):
        if self.unmapped:
            if value == "Unmapped":
                return

            # Remove unmapped item if setting the mapping.
            self.direction.removeItem(len(index_to_word))
            self.direction.setPalette(self.orig_palette)
            self.unmapped = False

        dir_ = index_to_setting[value]
        self.log.debug("Setting {0.class_}:{0.perm} direction to {1}".format(self.mapping, dir_))
        self.mapping.direction = dir_

    def set_weight(self, value):
        self.log.debug("Setting {0.class_}:{0.perm} weight to {1}".format(self.mapping, value))
        self.mapping.weight = int(value)

    def set_enabled(self, value):
        self.log.debug("Setting {0.class_}:{0.perm} enabled to {1}".format(self.mapping, value))
        self.mapping.enabled = value
<|endoftext|>


<commit_before># Copyright 2015, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools 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.
#
# SETools 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 SETools.  If not, see
# <http://www.gnu.org/licenses/>.
#

import logging

from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QWidget
from setools import TERuleQuery

from ..widget import SEToolsWidget
from .rulemodels import TERuleListModel
from .models import PermListModel, SEToolsListModel

class TERuleQueryTab(SEToolsWidget, QWidget):
    def __init__(self, tab, policy):
        super(TERuleQueryTab, self).__init__(tab)
        self.log = logging.getLogger(self.__class__.__name__)
        self.policy = policy
        self.query = TERuleQuery(policy)
        self.tab = tab
        self.setupUi()

    def setupUi(self):
        self.load_ui("terulequery.ui")

        # set up source/target/default autocompletion
        completion_list = [str(t) for t in self.policy.types()]
        completion_list.extend(str(a) for a in self.policy.typeattributes())
        completer_model = QStringListModel(self)
        completer_model.setStringList(sorted(completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(completer_model)
        self.source.setCompleter(self.type_completion)
        self.target.setCompleter(self.type_completion)

        # setup indications of errors on source/target
        self.source.setToolTip("Match the source type/attribute of the rule.")
        self.target.setToolTip("Match the target type/attribute of the rule.")
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # populate perm list
        self.perms_model = PermListModel(self, self.policy)
        self.perms.setModel(self.perms_model)

        # set up results
        self.table_results_model = TERuleListModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)

        # check expanders to make sure the display
        # is consistent with the initial .ui state
        self.toggle_criteria_frame()
        self.toggle_results_frame()
        self.toggle_notes_frame()

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.source_regex.toggled.connect(self.set_source)
        self.target_regex.toggled.connect(self.set_target)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.clear_class.clicked.connect(self.clear_tclass_selection)
        self.perms.selectionModel().selectionChanged.connect(self.set_perms)
        self.clear_perms.clicked.connect(self.clear_perms_selection)
        self.criteria_expander.clicked.connect(self.toggle_criteria_frame)
        self.results_expander.clicked.connect(self.toggle_results_frame)
        self.notes_expander.clicked.connect(self.toggle_notes_frame)

    #
    # Source criteria
    #

    def clear_source_error(self):
        self.source.setToolTip("Match the source type/attribute of the rule.")
        self.source.setPalette(self.orig_palette)

    def set_source(self):
        self.query.source_regex = self.source_regex.isChecked()

        try:
            self.query.source = self.source.text()
        except Exception as ex:
            self.source.setToolTip("Error: " + str(ex))
            self.source.setPalette(self.error_palette)

    #
    # Target criteria
    #

    def clear_target_error(self):
        self.target.setToolTip("Match the target type/attribute of the rule.")
        self.target.setPalette(self.orig_palette)

    def set_target(self):
        self.query.target_regex = self.target_regex.isChecked()

        try:
            self.query.target = self.target.text()
        except Exception as ex:
            self.target.setToolTip("Error: " + str(ex))
            self.target.setPalette(self.error_palette)

    #
    # Class criteria
    #

    def clear_tclass_selection(self):
        self.tclass.selectionModel().clearSelection()

    def set_tclass(self):
        selected_classes = []
        for index in self.tclass.selectionModel().selectedIndexes():
            selected_classes.append(self.class_model.data(index, Qt.UserRole))

        self.query.tclass = selected_classes
        self.perms_model.set_classes(selected_classes)

    #
    # Permissions criteria
    #

    def clear_perms_selection(self):
        self.perms.selectionModel().clearSelection()

    def set_perms(self):
        selected_perms = []
        for index in self.perms.selectionModel().selectedIndexes():
            selected_perms.append(self.perms_model.data(index, Qt.UserRole))

        self.query.perms = selected_perms

    #
    # Results runner
    #

    def run(self, button):
        # right now there is only one button.
        rule_types = []

        if self.allow.isChecked():
            rule_types.append("allow")
        if self.auditallow.isChecked():
            rule_types.append("auditallow")
        if self.neverallow.isChecked():
            rule_types.append("neverallow")
        if self.dontaudit.isChecked():
            rule_types.append("dontaudit")
        if self.type_transition.isChecked():
            rule_types.append("type_transition")
        if self.type_member.isChecked():
            rule_types.append("type_member")
        if self.type_change.isChecked():
            rule_types.append("type_change")

        self.query.ruletype = rule_types
        self.query.source_indirect = self.source_indirect.isChecked()
        self.query.target_indirect = self.target_indirect.isChecked()

        # update results table
        results = list(self.query.results())
        self.table_results_model.set_rules(results)

        # Column sizing
        headerview = self.table_results.horizontalHeader()
        headerview.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(4, QHeaderView.Stretch)
        headerview.setSectionResizeMode(5, QHeaderView.ResizeToContents)

        # update raw results
        self.raw_results.clear()
        for line in results:
            self.raw_results.appendPlainText(str(line))

        self.raw_results.moveCursor(QTextCursor.Start)

    #
    # Section expander handlers
    #

    def toggle_criteria_frame(self):
        if self.criteria_expander.isChecked():
            self.criteria_frame.show()
        else:
            self.criteria_frame.hide()

    def toggle_results_frame(self):
        if self.results_expander.isChecked():
            self.results_frame.show()
        else:
            self.results_frame.hide()

    def toggle_notes_frame(self):
        if self.notes_expander.isChecked():
            self.notes.show()
        else:
            self.notes.hide()
<commit_msg>TERuleQueryTab: only set column sizing once (on setupUi)<commit_after># Copyright 2015, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools 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.
#
# SETools 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 SETools.  If not, see
# <http://www.gnu.org/licenses/>.
#

import logging

from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QWidget
from setools import TERuleQuery

from ..widget import SEToolsWidget
from .rulemodels import TERuleListModel
from .models import PermListModel, SEToolsListModel

class TERuleQueryTab(SEToolsWidget, QWidget):
    def __init__(self, tab, policy):
        super(TERuleQueryTab, self).__init__(tab)
        self.log = logging.getLogger(self.__class__.__name__)
        self.policy = policy
        self.query = TERuleQuery(policy)
        self.tab = tab
        self.setupUi()

    def setupUi(self):
        self.load_ui("terulequery.ui")

        # set up source/target/default autocompletion
        completion_list = [str(t) for t in self.policy.types()]
        completion_list.extend(str(a) for a in self.policy.typeattributes())
        completer_model = QStringListModel(self)
        completer_model.setStringList(sorted(completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(completer_model)
        self.source.setCompleter(self.type_completion)
        self.target.setCompleter(self.type_completion)

        # setup indications of errors on source/target
        self.source.setToolTip("Match the source type/attribute of the rule.")
        self.target.setToolTip("Match the target type/attribute of the rule.")
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # populate perm list
        self.perms_model = PermListModel(self, self.policy)
        self.perms.setModel(self.perms_model)

        # set up results
        self.table_results_model = TERuleListModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)
        headerview = self.table_results.horizontalHeader()
        headerview.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        headerview.setSectionResizeMode(4, QHeaderView.Stretch)
        headerview.setSectionResizeMode(5, QHeaderView.ResizeToContents)

        # check expanders to make sure the display
        # is consistent with the initial .ui state
        self.toggle_criteria_frame()
        self.toggle_results_frame()
        self.toggle_notes_frame()

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.source_regex.toggled.connect(self.set_source)
        self.target_regex.toggled.connect(self.set_target)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.clear_class.clicked.connect(self.clear_tclass_selection)
        self.perms.selectionModel().selectionChanged.connect(self.set_perms)
        self.clear_perms.clicked.connect(self.clear_perms_selection)
        self.criteria_expander.clicked.connect(self.toggle_criteria_frame)
        self.results_expander.clicked.connect(self.toggle_results_frame)
        self.notes_expander.clicked.connect(self.toggle_notes_frame)

    #
    # Source criteria
    #

    def clear_source_error(self):
        self.source.setToolTip("Match the source type/attribute of the rule.")
        self.source.setPalette(self.orig_palette)

    def set_source(self):
        self.query.source_regex = self.source_regex.isChecked()

        try:
            self.query.source = self.source.text()
        except Exception as ex:
            self.source.setToolTip("Error: " + str(ex))
            self.source.setPalette(self.error_palette)

    #
    # Target criteria
    #

    def clear_target_error(self):
        self.target.setToolTip("Match the target type/attribute of the rule.")
        self.target.setPalette(self.orig_palette)

    def set_target(self):
        self.query.target_regex = self.target_regex.isChecked()

        try:
            self.query.target = self.target.text()
        except Exception as ex:
            self.target.setToolTip("Error: " + str(ex))
            self.target.setPalette(self.error_palette)

    #
    # Class criteria
    #

    def clear_tclass_selection(self):
        self.tclass.selectionModel().clearSelection()

    def set_tclass(self):
        selected_classes = []
        for index in self.tclass.selectionModel().selectedIndexes():
            selected_classes.append(self.class_model.data(index, Qt.UserRole))

        self.query.tclass = selected_classes
        self.perms_model.set_classes(selected_classes)

    #
    # Permissions criteria
    #

    def clear_perms_selection(self):
        self.perms.selectionModel().clearSelection()

    def set_perms(self):
        selected_perms = []
        for index in self.perms.selectionModel().selectedIndexes():
            selected_perms.append(self.perms_model.data(index, Qt.UserRole))

        self.query.perms = selected_perms

    #
    # Results runner
    #

    def run(self, button):
        # right now there is only one button.
        rule_types = []

        if self.allow.isChecked():
            rule_types.append("allow")
        if self.auditallow.isChecked():
            rule_types.append("auditallow")
        if self.neverallow.isChecked():
            rule_types.append("neverallow")
        if self.dontaudit.isChecked():
            rule_types.append("dontaudit")
        if self.type_transition.isChecked():
            rule_types.append("type_transition")
        if self.type_member.isChecked():
            rule_types.append("type_member")
        if self.type_change.isChecked():
            rule_types.append("type_change")

        self.query.ruletype = rule_types
        self.query.source_indirect = self.source_indirect.isChecked()
        self.query.target_indirect = self.target_indirect.isChecked()

        # update results table
        results = list(self.query.results())
        self.table_results_model.set_rules(results)

        # update raw results
        self.raw_results.clear()
        for line in results:
            self.raw_results.appendPlainText(str(line))

        self.raw_results.moveCursor(QTextCursor.Start)

    #
    # Section expander handlers
    #

    def toggle_criteria_frame(self):
        if self.criteria_expander.isChecked():
            self.criteria_frame.show()
        else:
            self.criteria_frame.hide()

    def toggle_results_frame(self):
        if self.results_expander.isChecked():
            self.results_frame.show()
        else:
            self.results_frame.hide()

    def toggle_notes_frame(self):
        if self.notes_expander.isChecked():
            self.notes.show()
        else:
            self.notes.hide()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from django.contrib.syndication.views import Feed
from django_cal.views import Events
from datetime import datetime, date
import django_cal
import locale
import dateutil

from hat.models import Strike, Region

locale.setlocale(locale.LC_ALL, "pt_PT.UTF-8")

tzlx = dateutil.tz.gettz('Europe/Lisbon')

def strikeItems():
    return Strike.objects.filter(start_date__gte=datetime.today().date()).exclude(canceled=True).order_by('start_date')[:10]

class RssFeed(Feed):
    """Generate an RSS of the strikes"""
    title = u'Hoje há greve?'
    link = ''
    description = u'Veja se consegue chegar ao trabalho. Lembre-se que as informações podem estar desactualizadas.'

    def items(self):
        return strikeItems()

    def item_title(self, strike):
        return strike.company.name + ' - ' + strike.region.name

    description_template = 'feeds/rss_description.html'

    def item_summary(self, strike):
        return strike.description

    def item_link(self, strike):
        return 'http://hagreve.com'

    def item_pubdate(self, strike):
        return strike.start_date

class IcsFeed(Events):
    def cal_name(self):
        return u'Hoje há greve?'

    def cal_desc(self):
        return u'Veja se consegue chegar ao trabalho. Lembre-se que as informações podem estar desactualizadas.'

    def items(self):
        return strikeItems()

    def item_summary(self, strike):
        return strike.description

    def item_title(self, strike):
        return strike.company.name + ' - ' + strike.region.name

    def item_start(self, strike):
        if strike.start_date == strike.end_date:
          return strike.start_date.date()
        return strike.start_date.replace(tzinfo=tzlx)

    def item_end(self, strike):
        return strike.end_date

    def item_description(self, strike):
        return 'Greve da empresa ' + strike.company.name + '\n' + 'De ' + str(strike.start_date) + ' a ' + str(strike.end_date.strftime) + '\n' + strike.description

    def item_link(self, strike):
        return 'https://hagreve.com'

<commit_msg>fixed summary<commit_after># -*- coding: utf-8 -*-
from django.contrib.syndication.views import Feed
from django_cal.views import Events
from datetime import datetime, date
import django_cal
import locale
import dateutil

from hat.models import Strike, Region

locale.setlocale(locale.LC_ALL, "pt_PT.UTF-8")

tzlx = dateutil.tz.gettz('Europe/Lisbon')

def strikeItems():
    return Strike.objects.filter(start_date__gte=datetime.today().date()).exclude(canceled=True).order_by('start_date')[:10]

class RssFeed(Feed):
    """Generate an RSS of the strikes"""
    title = u'Hoje há greve?'
    link = ''
    description = u'Veja se consegue chegar ao trabalho. Lembre-se que as informações podem estar desactualizadas.'

    def items(self):
        return strikeItems()

    def item_title(self, strike):
        return strike.company.name + ' - ' + strike.region.name

    description_template = 'feeds/rss_description.html'

    def item_summary(self, strike):
        return strike.company.name + ' - ' + strike.region.name

    def item_link(self, strike):
        return 'http://hagreve.com'

    def item_pubdate(self, strike):
        return strike.start_date

class IcsFeed(Events):
    def cal_name(self):
        return u'Hoje há greve?'

    def cal_desc(self):
        return u'Veja se consegue chegar ao trabalho. Lembre-se que as informações podem estar desactualizadas.'

    def items(self):
        return strikeItems()

    def item_summary(self, strike):
        return strike.description

    def item_title(self, strike):
        return strike.company.name + ' - ' + strike.region.name

    def item_start(self, strike):
        if strike.start_date == strike.end_date:
          return strike.start_date.date()
        return strike.start_date.replace(tzinfo=tzlx)

    def item_end(self, strike):
        return strike.end_date

    def item_description(self, strike):
        return 'Greve da empresa ' + strike.company.name + '\n' + 'De ' + str(strike.start_date) + ' a ' + str(strike.end_date.strftime) + '\n' + strike.description

    def item_link(self, strike):
        return 'https://hagreve.com'

<|endoftext|>


<commit_before>"""Helper methods for various modules."""
from collections.abc import MutableSet
from itertools import chain
import threading
from datetime import datetime
import re
import enum
import socket
import random
import string
from functools import wraps
from types import MappingProxyType
from unicodedata import normalize

from typing import Any, Optional, TypeVar, Callable, Sequence, KeysView, Union

from .dt import as_local, utcnow

T = TypeVar('T')
U = TypeVar('U')

RE_SANITIZE_FILENAME = re.compile(r'(~|\.\.|/|\\)')
RE_SANITIZE_PATH = re.compile(r'(~|\.(\.)+)')
RE_SLUGIFY = re.compile(r'[^a-z0-9_]+')
TBL_SLUGIFY = {
    ord('ß'): 'ss'
}

def sanitize_filename(filename: str) -> str:
    r"""Sanitize a filename by removing .. / and \\."""
    return RE_SANITIZE_FILENAME.sub("", filename)

def sanitize_path(path: str) -> str:
    """Sanitize a path by removing ~ and .."""
    return RE_SANITIZE_PATH.sub("", path)

def slugify(text: str) -> str:
    """Slugify a given text."""
    text = normalize('NFKD', text)
    text = text.lower()
    text = text.replace(" ", "_")
    text = text.translate(TBL_SLUGIFY)
    text = RE_SLUGIFY.sub("", text)

    return text

def repr_helper(inp: Any) -> str:
    """Help creating a more readable string representation of objects."""
    if isinstance(inp, (dict, MappingProxyType)):
        return ", ".join(
            repr_helper(key)+"="+repr_helper(item) for key, item
            in inp.items())
    elif isinstance(inp, datetime):
        return as_local(inp).isoformat()

    return str(inp)

def convert(value: T, to_type: Callable[[T], U],
            default: Optional[U]=None) -> Optional[U]:
    """Convert value to to_type, returns default if fails."""
    try:
        return default if value is None else to_type(value)
    except (ValueError, TypeError):
        # If value could not be converted
        return default

def ensure_unique_string(preferred_string: str, current_strings:
                         Union[Sequence[str], KeysView[str]]) -> str:
    """Return a string that is not present in current_strings.

    If preferred string exists will append _2, _3, ..
    """
    test_string = preferred_string
    current_strings_set = set(current_strings)

    tries = 1

    while test_string in current_strings_set:
        tries += 1
        test_string = "{}_{}".format(preferred_string, tries)

    return test_string

# Taken from: http://stackoverflow.com/a/11735897
def get_local_ip():
    """Try to determine the local IP address of the machine."""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # Use Google Public DNS server to determine own IP
        sock.connect(('8.8.8.8', 80))

        return sock.getsockname()[0]
    except socket.error:
        try:
            return socket.gethostbyname(socket.gethostname())
        except socket.gaierror:
            return '127.0.0.1'
    finally:
        sock.close()

# Taken from http://stackoverflow.com/a/23728630
def get_random_string(length=10):
    """Return a random string with letters and digits."""
    generator = random.SystemRandom()
    source_chars = string.ascii_letters + string.digits

    return ''.join(generator.choice(source_chars) for _ in range(length))

class OrderedEnum(enum.Enum):
    """Taken from Python 3.4.0 docs."""

    # pylint: disable=no-init
    def __ge__(self, other):
        """Return the greater than element."""
        if self.__class__ is other.__class__:
            return self.value >= other.value
        return NotImplemented

    def __gt__(self, other):
        """Return the greater element."""
        if self.__class__ is other.__class__:
            return self.value > other.value
        return NotImplemented

    def __le__(self, other):
        """Return the lower than element."""
        if self.__class__ is other.__class__:
            return self.value <= other.value
        return NotImplemented

    def __lt__(self, other):
        """Return the lower element."""
        if self.__class__ is other.__class__:
            return self.value < other.value
        return NotImplemented

class OrderedSet(MutableSet):
    """Ordered set taken from http://code.activestate.com/recipes/576694/."""

    def __init__(self, iterable=None):
        """Initialize the set."""
        self.end = end = []
        end += [None, end, end]         # sentinel node for doubly linked list
        self.map = {}                   # key --> [key, prev, next]
        if iterable is not None:
            self |= iterable

    def __len__(self):
        """Return the length of the set."""
        return len(self.map)

    def __contains__(self, key):
        """Check if key is in set."""
        return key in self.map

    def add(self, key):
        """Add an element to the end of the set."""
        if key not in self.map:
            end = self.end
            curr = end[1]
            curr[2] = end[1] = self.map[key] = [key, curr, end]

    def promote(self, key):
        """Promote element to beginning of the set, add if not there."""
        if key in self.map:
            self.discard(key)

        begin = self.end[2]
        curr = begin[1]
        curr[2] = begin[1] = self.map[key] = [key, curr, begin]

    def discard(self, key):
        """Discard an element from the set."""
        if key in self.map:
            key, prev_item, next_item = self.map.pop(key)
            prev_item[2] = next_item
            next_item[1] = prev_item

    def __iter__(self):
        """Iterate of the set."""
        end = self.end
        curr = end[2]
        while curr is not end:
            yield curr[0]
            curr = curr[2]

    def __reversed__(self):
        """Reverse the ordering."""
        end = self.end
        curr = end[1]
        while curr is not end:
            yield curr[0]
            curr = curr[1]

    # pylint: disable=arguments-differ
    def pop(self, last=True):
        """Pop element of the end of the set.

        Set last=False to pop from the beginning.
        """
        if not self:
            raise KeyError('set is empty')
        key = self.end[1][0] if last else self.end[2][0]
        self.discard(key)
        return key

    def update(self, *args):
        """Add elements from args to the set."""
        for item in chain(*args):
            self.add(item)

    def __repr__(self):
        """Return the representation."""
        if not self:
            return '%s()' % (self.__class__.__name__,)
        return '%s(%r)' % (self.__class__.__name__, list(self))

    def __eq__(self, other):
        """Return the comparision."""
        if isinstance(other, OrderedSet):
            return len(self) == len(other) and list(self) == list(other)
        return set(self) == set(other)

class Throttle(object):
    """A class for throttling the execution of tasks.

    This method decorator adds a cooldown to a method to prevent it from being
    called more then 1 time within the timedelta interval `min_time` after it
    returned its result.

    Calling a method a second time during the interval will return None.

    Pass keyword argument `no_throttle=True` to the wrapped method to make
    the call not throttled.

    Decorator takes in an optional second timedelta interval to throttle the
    'no_throttle' calls.

    Adds a datetime attribute `last_call` to the method.
    """

    def __init__(self, min_time, limit_no_throttle=None):
        """Initialize the throttle."""
        self.min_time = min_time
        self.limit_no_throttle = limit_no_throttle

    def __call__(self, method):
        """Caller for the throttle."""
        if self.limit_no_throttle is not None:
            method = Throttle(self.limit_no_throttle)(method)

        # Different methods that can be passed in:
        #  - a function
        #  - an unbound function on a class
        #  - a method (bound function on a class)

        # We want to be able to differentiate between function and unbound
        # methods (which are considered functions).
        # All methods have the classname in their qualname separated by a '.'
        # Functions have a '.' in their qualname if defined inline, but will
        # be prefixed by '.<locals>.' so we strip that out.
        is_func = (not hasattr(method, '__self__') and
                   '.' not in method.__qualname__.split('.<locals>.')[-1])

        @wraps(method)
        def wrapper(*args, **kwargs):
            """Wrap that allows wrapped to be called only once per min_time.

            If we cannot acquire the lock, it is running so return None.
            """
            # pylint: disable=protected-access
            if hasattr(method, '__self__'):
                host = method.__self__
            elif is_func:
                host = wrapper
            else:
                host = args[0] if args else wrapper

            if not hasattr(host, '_throttle'):
                host._throttle = {}

            if id(self) not in host._throttle:
                host._throttle[id(self)] = [threading.Lock(), None]
            throttle = host._throttle[id(self)]

            if not throttle[0].acquire(False):
                return None

            # Check if method is never called or no_throttle is given
            force = not throttle[1] or kwargs.pop('no_throttle', False)

            try:
                if force or utcnow() - throttle[1] > self.min_time:
                    result = method(*args, **kwargs)
                    throttle[1] = utcnow()
                    return result

                return None
            finally:
                throttle[0].release()

        return wrapper
<commit_msg>Always consume the no_throttle keyword argument. (#11126)<commit_after>"""Helper methods for various modules."""
from collections.abc import MutableSet
from itertools import chain
import threading
from datetime import datetime
import re
import enum
import socket
import random
import string
from functools import wraps
from types import MappingProxyType
from unicodedata import normalize

from typing import Any, Optional, TypeVar, Callable, Sequence, KeysView, Union

from .dt import as_local, utcnow

T = TypeVar('T')
U = TypeVar('U')

RE_SANITIZE_FILENAME = re.compile(r'(~|\.\.|/|\\)')
RE_SANITIZE_PATH = re.compile(r'(~|\.(\.)+)')
RE_SLUGIFY = re.compile(r'[^a-z0-9_]+')
TBL_SLUGIFY = {
    ord('ß'): 'ss'
}

def sanitize_filename(filename: str) -> str:
    r"""Sanitize a filename by removing .. / and \\."""
    return RE_SANITIZE_FILENAME.sub("", filename)

def sanitize_path(path: str) -> str:
    """Sanitize a path by removing ~ and .."""
    return RE_SANITIZE_PATH.sub("", path)

def slugify(text: str) -> str:
    """Slugify a given text."""
    text = normalize('NFKD', text)
    text = text.lower()
    text = text.replace(" ", "_")
    text = text.translate(TBL_SLUGIFY)
    text = RE_SLUGIFY.sub("", text)

    return text

def repr_helper(inp: Any) -> str:
    """Help creating a more readable string representation of objects."""
    if isinstance(inp, (dict, MappingProxyType)):
        return ", ".join(
            repr_helper(key)+"="+repr_helper(item) for key, item
            in inp.items())
    elif isinstance(inp, datetime):
        return as_local(inp).isoformat()

    return str(inp)

def convert(value: T, to_type: Callable[[T], U],
            default: Optional[U]=None) -> Optional[U]:
    """Convert value to to_type, returns default if fails."""
    try:
        return default if value is None else to_type(value)
    except (ValueError, TypeError):
        # If value could not be converted
        return default

def ensure_unique_string(preferred_string: str, current_strings:
                         Union[Sequence[str], KeysView[str]]) -> str:
    """Return a string that is not present in current_strings.

    If preferred string exists will append _2, _3, ..
    """
    test_string = preferred_string
    current_strings_set = set(current_strings)

    tries = 1

    while test_string in current_strings_set:
        tries += 1
        test_string = "{}_{}".format(preferred_string, tries)

    return test_string

# Taken from: http://stackoverflow.com/a/11735897
def get_local_ip():
    """Try to determine the local IP address of the machine."""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # Use Google Public DNS server to determine own IP
        sock.connect(('8.8.8.8', 80))

        return sock.getsockname()[0]
    except socket.error:
        try:
            return socket.gethostbyname(socket.gethostname())
        except socket.gaierror:
            return '127.0.0.1'
    finally:
        sock.close()

# Taken from http://stackoverflow.com/a/23728630
def get_random_string(length=10):
    """Return a random string with letters and digits."""
    generator = random.SystemRandom()
    source_chars = string.ascii_letters + string.digits

    return ''.join(generator.choice(source_chars) for _ in range(length))

class OrderedEnum(enum.Enum):
    """Taken from Python 3.4.0 docs."""

    # pylint: disable=no-init
    def __ge__(self, other):
        """Return the greater than element."""
        if self.__class__ is other.__class__:
            return self.value >= other.value
        return NotImplemented

    def __gt__(self, other):
        """Return the greater element."""
        if self.__class__ is other.__class__:
            return self.value > other.value
        return NotImplemented

    def __le__(self, other):
        """Return the lower than element."""
        if self.__class__ is other.__class__:
            return self.value <= other.value
        return NotImplemented

    def __lt__(self, other):
        """Return the lower element."""
        if self.__class__ is other.__class__:
            return self.value < other.value
        return NotImplemented

class OrderedSet(MutableSet):
    """Ordered set taken from http://code.activestate.com/recipes/576694/."""

    def __init__(self, iterable=None):
        """Initialize the set."""
        self.end = end = []
        end += [None, end, end]         # sentinel node for doubly linked list
        self.map = {}                   # key --> [key, prev, next]
        if iterable is not None:
            self |= iterable

    def __len__(self):
        """Return the length of the set."""
        return len(self.map)

    def __contains__(self, key):
        """Check if key is in set."""
        return key in self.map

    def add(self, key):
        """Add an element to the end of the set."""
        if key not in self.map:
            end = self.end
            curr = end[1]
            curr[2] = end[1] = self.map[key] = [key, curr, end]

    def promote(self, key):
        """Promote element to beginning of the set, add if not there."""
        if key in self.map:
            self.discard(key)

        begin = self.end[2]
        curr = begin[1]
        curr[2] = begin[1] = self.map[key] = [key, curr, begin]

    def discard(self, key):
        """Discard an element from the set."""
        if key in self.map:
            key, prev_item, next_item = self.map.pop(key)
            prev_item[2] = next_item
            next_item[1] = prev_item

    def __iter__(self):
        """Iterate of the set."""
        end = self.end
        curr = end[2]
        while curr is not end:
            yield curr[0]
            curr = curr[2]

    def __reversed__(self):
        """Reverse the ordering."""
        end = self.end
        curr = end[1]
        while curr is not end:
            yield curr[0]
            curr = curr[1]

    # pylint: disable=arguments-differ
    def pop(self, last=True):
        """Pop element of the end of the set.

        Set last=False to pop from the beginning.
        """
        if not self:
            raise KeyError('set is empty')
        key = self.end[1][0] if last else self.end[2][0]
        self.discard(key)
        return key

    def update(self, *args):
        """Add elements from args to the set."""
        for item in chain(*args):
            self.add(item)

    def __repr__(self):
        """Return the representation."""
        if not self:
            return '%s()' % (self.__class__.__name__,)
        return '%s(%r)' % (self.__class__.__name__, list(self))

    def __eq__(self, other):
        """Return the comparision."""
        if isinstance(other, OrderedSet):
            return len(self) == len(other) and list(self) == list(other)
        return set(self) == set(other)

class Throttle(object):
    """A class for throttling the execution of tasks.

    This method decorator adds a cooldown to a method to prevent it from being
    called more then 1 time within the timedelta interval `min_time` after it
    returned its result.

    Calling a method a second time during the interval will return None.

    Pass keyword argument `no_throttle=True` to the wrapped method to make
    the call not throttled.

    Decorator takes in an optional second timedelta interval to throttle the
    'no_throttle' calls.

    Adds a datetime attribute `last_call` to the method.
    """

    def __init__(self, min_time, limit_no_throttle=None):
        """Initialize the throttle."""
        self.min_time = min_time
        self.limit_no_throttle = limit_no_throttle

    def __call__(self, method):
        """Caller for the throttle."""
        if self.limit_no_throttle is not None:
            method = Throttle(self.limit_no_throttle)(method)

        # Different methods that can be passed in:
        #  - a function
        #  - an unbound function on a class
        #  - a method (bound function on a class)

        # We want to be able to differentiate between function and unbound
        # methods (which are considered functions).
        # All methods have the classname in their qualname separated by a '.'
        # Functions have a '.' in their qualname if defined inline, but will
        # be prefixed by '.<locals>.' so we strip that out.
        is_func = (not hasattr(method, '__self__') and
                   '.' not in method.__qualname__.split('.<locals>.')[-1])

        @wraps(method)
        def wrapper(*args, **kwargs):
            """Wrap that allows wrapped to be called only once per min_time.

            If we cannot acquire the lock, it is running so return None.
            """
            # pylint: disable=protected-access
            if hasattr(method, '__self__'):
                host = method.__self__
            elif is_func:
                host = wrapper
            else:
                host = args[0] if args else wrapper

            if not hasattr(host, '_throttle'):
                host._throttle = {}

            if id(self) not in host._throttle:
                host._throttle[id(self)] = [threading.Lock(), None]
            throttle = host._throttle[id(self)]

            if not throttle[0].acquire(False):
                return None

            # Check if method is never called or no_throttle is given
            force = kwargs.pop('no_throttle', False) or not throttle[1]

            try:
                if force or utcnow() - throttle[1] > self.min_time:
                    result = method(*args, **kwargs)
                    throttle[1] = utcnow()
                    return result

                return None
            finally:
                throttle[0].release()

        return wrapper
<|endoftext|>


<commit_before>from pony.orm import *
import pony.orm
from typing import cast, Optional

from horsefax.telegram.services.command import Command

from ..core import HorseFaxBot, ModuleTools, BaseModule, ChatService
from ..db import db
from .tracking import TelegramUser

class PingGroup(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(str, unique=True)
    added_by = pony.orm.Optional(int)
    members = Set(TelegramUser)

class CollectionModule(BaseModule):
    def __init__(self, bot: HorseFaxBot, tools: ModuleTools) -> None:
        self.bot = bot
        self.util = tools
        self.util.register_command("addgroup", self.add_group)
        self.util.register_command("joingroup", self.join_group)
        self.util.register_command("leavegroup", self.leave_group)
        self.util.register_command("removegroup", self.remove_group)
        self.util.register_command("listgroups", self.list_groups)
        self.util.register_command("ping", self.ping_group)

    @db_session
    def add_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/addgroup <group name>`"
        name = command.args[0].lower()
        if PingGroup.get(name=name) is None:
            group = PingGroup(name=name, added_by=command.message.sender.id)
            return f"Created group `{group.name}`. Join it using `/joingroup {group.name}`."
        else:
            return f"The group {name} already exists. Join it using `/joingroup {group.name}`."

    @db_session
    def join_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/joingroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        user = TelegramUser[command.message.sender.id]
        if user in group.members:
            return f"You are already a member of the group `{name}`."
        if user.username is None:
            return "You cannot join a group unless you have a set a username in Telegram."
        group.members.add(user)
        return f"Joined {group.name}, which now has {len(group.members)} member(s)."

    @db_session
    def ping_group(self, command: Command) -> Optional[str]:
        if len(command.args) < 2:
            return "Syntax: `/ping <group name> <message>`"
        message = ' '.join(command.args[1:])
        group_name = command.args[0].lower()
        group = PingGroup.get(name=group_name)
        if group is None:
            return f"The group `{group_name}` does not exist."

        if len(group.members) == 0:
            return f"The group `{group.name}` has np members."
        output = f"{' '.join(f'@{x}' for x in group.members.username if x)}: {message}"
        self.bot.message(command.message.chat, output, parsing=ChatService.ParseMode.NONE)

    @db_session
    def leave_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/leavegroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        user = TelegramUser[command.message.sender.id]
        if user not in group.members:
            return f"You are not a member of the group `{group.name}`."
        group.members.remove(user)
        return f"Removed you from {group.name}, which now has {len(group.members)} member(s)."

    @db_session
    def remove_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/removegroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        member_count = len(group.members)
        group.delete()
        return f"Deleted group {name}, which had {member_count} member(s)."

    @db_session
    def list_groups(self, command: Command) -> str:
        return f"The following groups exist: " \
               f"{', '.join(f'`{x.name}`' for x in PingGroup.select().order_by(PingGroup.name))}"
<commit_msg>Add /showgroup<commit_after>from pony.orm import *
import pony.orm
from typing import cast, Optional

from horsefax.telegram.services.command import Command

from ..core import HorseFaxBot, ModuleTools, BaseModule, ChatService
from ..db import db
from .tracking import TelegramUser

class PingGroup(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(str, unique=True)
    added_by = pony.orm.Optional(int)
    members = Set(TelegramUser)

class CollectionModule(BaseModule):
    def __init__(self, bot: HorseFaxBot, tools: ModuleTools) -> None:
        self.bot = bot
        self.util = tools
        self.util.register_command("addgroup", self.add_group)
        self.util.register_command("joingroup", self.join_group)
        self.util.register_command("leavegroup", self.leave_group)
        self.util.register_command("removegroup", self.remove_group)
        self.util.register_command("listgroups", self.list_groups)
        self.util.register_command("showgroup", self.show_group)
        self.util.register_command("ping", self.ping_group)

    @db_session
    def add_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/addgroup <group name>`"
        name = command.args[0].lower()
        if PingGroup.get(name=name) is None:
            group = PingGroup(name=name, added_by=command.message.sender.id)
            return f"Created group `{group.name}`. Join it using `/joingroup {group.name}`."
        else:
            return f"The group {name} already exists. Join it using `/joingroup {group.name}`."

    @db_session
    def join_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/joingroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        user = TelegramUser[command.message.sender.id]
        if user in group.members:
            return f"You are already a member of the group `{name}`."
        if user.username is None:
            return "You cannot join a group unless you have a set a username in Telegram."
        group.members.add(user)
        return f"Joined {group.name}, which now has {len(group.members)} member(s)."

    @db_session
    def ping_group(self, command: Command) -> Optional[str]:
        if len(command.args) < 2:
            return "Syntax: `/ping <group name> <message>`"
        message = ' '.join(command.args[1:])
        group_name = command.args[0].lower()
        group = PingGroup.get(name=group_name)
        if group is None:
            return f"The group `{group_name}` does not exist."

        if len(group.members) == 0:
            return f"The group `{group.name}` has np members."
        output = f"{' '.join(f'@{x}' for x in group.members.username if x)}: {message}"
        self.bot.message(command.message.chat, output, parsing=ChatService.ParseMode.NONE)

    @db_session
    def leave_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/leavegroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        user = TelegramUser[command.message.sender.id]
        if user not in group.members:
            return f"You are not a member of the group `{group.name}`."
        group.members.remove(user)
        return f"Removed you from {group.name}, which now has {len(group.members)} member(s)."

    @db_session
    def remove_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/removegroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"No such group: `{name}`."
        member_count = len(group.members)
        group.delete()
        return f"Deleted group {name}, which had {member_count} member(s)."

    @db_session
    def list_groups(self, command: Command) -> str:
        return f"The following groups exist: " \
               f"{', '.join(f'`{x.name}`' for x in PingGroup.select().order_by(PingGroup.name))}"

    @db_session
    def show_group(self, command: Command) -> str:
        if len(command.args) != 1:
            return "Syntax: `/showgroup <group name>`"
        name = command.args[0].lower()
        group = PingGroup.get(name=name)
        if group is None:
            return f"The group `{group_name}` does not exist."

        if len(group.members) == 0:
            return f"The group `{group.name}` has np members."

        return f"`{name}`: {', '.join(x for x in group.members.username if x)}"
<|endoftext|>


<commit_before>#
# ------------------------------------------------------------
# Copyright (c) All rights reserved
# SiLab, Institute of Physics, University of Bonn
# ------------------------------------------------------------
#

from basil.dut import Base

class RegisterLayer(Base):

    def __init__(self, driver, conf):
        super(RegisterLayer, self).__init__(conf)
        self._drv = driver

    def __getattr__(self, name):
        if not hasattr(getattr(self._drv, name), '__call__'):
            return getattr(self._drv, name)

        def method(*args, **kargs):
            arg = ()
            if 'arg_names' in self._conf:
                for i in range(len(args)):
                    kargs[self._conf['arg_names'][i]] = args[i]
            else:
                arg = args

            if 'arg_add' in self._conf:
                for argn in self._conf['arg_add']:
                    kargs[argn] = self._conf['arg_add'][argn]

            attr = getattr(self._drv, name)
            return attr(*arg, **kargs)

        return method
<commit_msg>ENH: cleanup<commit_after>#
# ------------------------------------------------------------
# Copyright (c) All rights reserved
# SiLab, Institute of Physics, University of Bonn
# ------------------------------------------------------------
#

from basil.dut import Base

class RegisterLayer(Base):
    def __init__(self, driver, conf):
        super(RegisterLayer, self).__init__(conf)
        self._drv = driver

    def __getattr__(self, name):
        if not hasattr(getattr(self._drv, name), '__call__'):
            return getattr(self._drv, name)

        def method(*args, **kargs):
            arg = ()
            if 'arg_names' in self._conf:
                for i in range(len(args)):
                    kargs[self._conf['arg_names'][i]] = args[i]
            else:
                arg = args

            if 'arg_add' in self._conf:
                for argn in self._conf['arg_add']:
                    kargs[argn] = self._conf['arg_add'][argn]

            attr = getattr(self._drv, name)
            return attr(*arg, **kargs)

        return method
<|endoftext|>


<commit_before>
import numpy as np

import roslib; roslib.load_manifest('hrl_lib')
import rospy
import visualization_msgs.msg as vm
import geometry_msgs.msg as gm
import std_msgs.msg as sdm

import hrl_lib.transforms as tr

##
# Creates a dictionary containing marker constants indexed by friendly names
def create_mdict():
    mdict = {}
    mdict['arrow']            = vm.Marker.ARROW
    mdict['cube']             = vm.Marker.CUBE
    mdict['sphere']           = vm.Marker.SPHERE
    mdict['cylinder']         = vm.Marker.CYLINDER
    mdict['line_strip']       = vm.Marker.LINE_STRIP
    mdict['line_list']        = vm.Marker.LINE_LIST
    mdict['cube_list']        = vm.Marker.CUBE_LIST
    mdict['sphere_list']      = vm.Marker.SPHERE_LIST
    mdict['points']           = vm.Marker.POINTS
    mdict['text_view_facing'] = vm.Marker.TEXT_VIEW_FACING
    mdict['mesh_resource']    = vm.Marker.MESH_RESOURCE
    mdict['triangle_list']    = vm.Marker.TRIANGLE_LIST
    return mdict

##
# Create a visualization_msgs.Marker message containing all the given points
def list_marker(points, colors, scale, mtype, mframe, duration=10.0, m_id=0):
    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()[mtype]
    m.action = vm.Marker.ADD
    m.points = [gm.Point(points[0,i], points[1,i], points[2,i]) for i in range(points.shape[1])]
    #pdb.set_trace()
    m.colors = [sdm.ColorRGBA(colors[0,i], colors[1,i], colors[2,i], colors[3,i]) for i in range(colors.shape[1])]

    m.color.r = 1.
    m.color.g = 0.
    m.color.b = 0.
    m.color.a = 1.
    m.scale.x = scale[0]
    m.scale.y = scale[1]
    m.scale.z = scale[2]

    m.lifetime = rospy.Duration(duration)

    return m

##
# Create a visualization_msgs.Marker message given a point
def single_marker(point, orientation, mtype, mframe, scale=[.2,.2,.2], color=[1.0, 0, 0,.5], duration=10.0, m_id=0):
    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()[mtype]
    m.action = vm.Marker.ADD

    m.pose.position.x = point[0,0]
    m.pose.position.y = point[1,0]
    m.pose.position.z = point[2,0]
    m.pose.orientation.x = orientation[0,0]
    m.pose.orientation.y = orientation[1,0]
    m.pose.orientation.z = orientation[2,0]
    m.pose.orientation.w = orientation[3,0]

    m.scale.x = scale[0]
    m.scale.y = scale[1]
    m.scale.z = scale[2]
    m.color.r = color[0]
    m.color.g = color[1]
    m.color.b = color[2]
    m.color.a = color[3]
    m.lifetime = rospy.Duration(duration)
    return m

##
# Creates a Marker message to display a coordinate frame
def create_frame_marker(center, frame, line_len, frame_id, m_id=0):
    clist = []
    plist = []
    alpha = line_len
    for i in range(3):
        colors = np.matrix(np.zeros((4,2)))
        colors[i,:] = 1.0
        colors[3,:] = 1.0
        clist.append(colors)
        plist.append(np.column_stack([center, center+ alpha * frame[:,i]]))
    return list_marker(np.column_stack(plist), np.column_stack(clist),
                       [.01, 0, 0], 'line_list', frame_id, m_id=m_id)

## make a quaternion from an arrow direction.
# can use this quaternion as the pose of the arrow marker to vizualise
# in rviz.
# @param direc - 3x1 np matrix.
# @return quaternion as a 4x1 np matrix
def arrow_direction_to_quat(direc):
    direc = direc / np.linalg.norm(direc)
    t = np.matrix([1.,0.,0.]).T
    if abs((t.T*direc)[0,0]) > 0.866:
        t = np.matrix([0.,1.,0.]).T

    v1 = direc
    v2 = t - (t.T*v1)[0,0] * v1
    v2 = v2 / np.linalg.norm(v2)
    v3 = np.matrix(np.cross(v1.A1, v2.A1)).T
    rot_mat = np.column_stack([v1, v2, v3])
    q = np.matrix(tr.matrix_to_quaternion(rot_mat)).T
    return q

<commit_msg>M    hrl_lib/src/hrl_lib/viz.py added new viz options<commit_after>
import numpy as np

import roslib; roslib.load_manifest('hrl_lib')
import rospy
import visualization_msgs.msg as vm
import geometry_msgs.msg as gm
import std_msgs.msg as sdm

import hrl_lib.transforms as tr

##
# Creates a dictionary containing marker constants indexed by friendly names
def create_mdict():
    mdict = {}
    mdict['arrow']            = vm.Marker.ARROW
    mdict['cube']             = vm.Marker.CUBE
    mdict['sphere']           = vm.Marker.SPHERE
    mdict['cylinder']         = vm.Marker.CYLINDER
    mdict['line_strip']       = vm.Marker.LINE_STRIP
    mdict['line_list']        = vm.Marker.LINE_LIST
    mdict['cube_list']        = vm.Marker.CUBE_LIST
    mdict['sphere_list']      = vm.Marker.SPHERE_LIST
    mdict['points']           = vm.Marker.POINTS
    mdict['text_view_facing'] = vm.Marker.TEXT_VIEW_FACING
    mdict['mesh_resource']    = vm.Marker.MESH_RESOURCE
    mdict['triangle_list']    = vm.Marker.TRIANGLE_LIST
    return mdict

##
# Create a visualization_msgs.Marker message containing all the given points
def list_marker(points, colors, scale, mtype, mframe, duration=10.0, m_id=0):
    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()[mtype]
    m.action = vm.Marker.ADD
    m.points = [gm.Point(points[0,i], points[1,i], points[2,i]) for i in range(points.shape[1])]
    #pdb.set_trace()
    m.colors = [sdm.ColorRGBA(colors[0,i], colors[1,i], colors[2,i], colors[3,i]) for i in range(colors.shape[1])]

    m.color.r = 1.
    m.color.g = 0.
    m.color.b = 0.
    m.color.a = 1.
    m.scale.x = scale[0]
    m.scale.y = scale[1]
    m.scale.z = scale[2]

    m.lifetime = rospy.Duration(duration)

    return m

def text_marker(text, center, color, scale, mframe,
        duration=10.0, m_id=0):

    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()['text_view_facing']
    m.action = vm.Marker.ADD
    m.text = text
    m.scale.z = scale
    m.pose.position.x = center[0,0]
    m.pose.position.y = center[1,0]
    m.pose.position.z = center[2,0]
    m.lifetime = rospy.Duration(duration)

    return m

def circle_marker(center, radius, scale, color, mframe, z=.03, duration=10.0, m_id=0, resolution=1.):
    angles = np.matrix(np.arange(0, 360., resolution)).T
    xs = center[0,0] + np.cos(angles) * radius
    ys = center[1,0] + np.sin(angles) * radius
    z = .03

    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()['line_strip']
    m.action = vm.Marker.ADD
    m.points = [gm.Point(xs[i,0], ys[i,0], z) for i in range(angles.shape[0])]
    m.colors = [sdm.ColorRGBA(color[0,0], color[1,0], color[2,0], color[3,0]) for i in range(angles.shape[0])]
    m.scale.x = scale
    m.lifetime = rospy.Duration(duration)
    return m

##
# Create a visualization_msgs.Marker message given a point
def single_marker(point, orientation, mtype, mframe, scale=[.2,.2,.2], color=[1.0, 0, 0,.5], duration=10.0, m_id=0):
    m = vm.Marker()
    m.header.frame_id = mframe
    m.id = m_id
    m.type = create_mdict()[mtype]
    m.action = vm.Marker.ADD

    m.pose.position.x = point[0,0]
    m.pose.position.y = point[1,0]
    m.pose.position.z = point[2,0]
    m.pose.orientation.x = orientation[0,0]
    m.pose.orientation.y = orientation[1,0]
    m.pose.orientation.z = orientation[2,0]
    m.pose.orientation.w = orientation[3,0]

    m.scale.x = scale[0]
    m.scale.y = scale[1]
    m.scale.z = scale[2]
    m.color.r = color[0]
    m.color.g = color[1]
    m.color.b = color[2]
    m.color.a = color[3]
    m.lifetime = rospy.Duration(duration)
    return m

##
# Creates a Marker message to display a coordinate frame
def create_frame_marker(center, frame, line_len, frame_id, m_id=0):
    clist = []
    plist = []
    alpha = line_len
    for i in range(3):
        colors = np.matrix(np.zeros((4,2)))
        colors[i,:] = 1.0
        colors[3,:] = 1.0
        clist.append(colors)
        plist.append(np.column_stack([center, center+ alpha * frame[:,i]]))
    return list_marker(np.column_stack(plist), np.column_stack(clist),
                       [.01, 0, 0], 'line_list', frame_id, m_id=m_id)

## make a quaternion from an arrow direction.
# can use this quaternion as the pose of the arrow marker to vizualise
# in rviz.
# @param direc - 3x1 np matrix.
# @return quaternion as a 4x1 np matrix
def arrow_direction_to_quat(direc):
    direc = direc / np.linalg.norm(direc)
    t = np.matrix([1.,0.,0.]).T
    if abs((t.T*direc)[0,0]) > 0.866:
        t = np.matrix([0.,1.,0.]).T

    v1 = direc
    v2 = t - (t.T*v1)[0,0] * v1
    v2 = v2 / np.linalg.norm(v2)
    v3 = np.matrix(np.cross(v1.A1, v2.A1)).T
    rot_mat = np.column_stack([v1, v2, v3])
    q = np.matrix(tr.matrix_to_quaternion(rot_mat)).T
    return q

<|endoftext|>


<commit_before>import simplejson as json
import sys, re

# load the cmu dict
try:
    cmu = json.load(open('cmu_dict.json'))
except:
    print "Converted CMU dict not found"
    sys.exit(0)

SubSyl = [
       'cial',
       'tia',
       'cius',
       'cious',
       'giu',              # belgium!
       'ion',
       'iou',
       'sia$',
       '.ely$',             # absolutely! (but not ely!)
      ]

AddSyl = [
       'ia',
       'riet',
       'dien',
       'iu',
       'io',
       'ii',
       '[aeiouym]bl$',     # -Vble, plus -mble
       '[aeiou]{3}',       # agreeable
       '^mc',
       'ism$',             # -isms
       '([^aeiouy])\1l$',  # middle twiddle battle bottle, etc.
       '[^l]lien',         # alien, salient [1]
           '^coa[dglx].',      # [2]
       '[^gq]ua[^auieo]',  # i think this fixes more than it breaks
       'dnt$',           # couldn't
      ]

def _guess_sy_count(word):
    """If we can't lookup the word, then guess its syllables count. This is
    (heavily) based on Greg Fast's Perl module Lingua::EN::Syllables. But
    the bugs are mine."""
    mungedword = re.sub('e$','',word.lower())
    splitword = re.split(r'[^aeiouy]+', mungedword)
    splitword = [ x for x in splitword if (x != '') ] # hmm
    syllables = 0
    for i in SubSyl:
        if re.search(i,mungedword):
            syllables -= 1
    for i in AddSyl:
        if re.search(i,mungedword):
            syllables += 1
    if len(mungedword) == 1: syllables =+ 1
    syllables += len(splitword)
    if syllables == 0: syllables = 1
    return syllables

def _count_syllables(word):
    if cmu.has_key(word):
        return cmu[word]
    else:
        return _guess_sy_count(word)

def check_string(to_check):

    haiku_form = [5,12,17]

    upper = to_check.upper()
    split = upper.split(' ')

    for count in haiku_form:
        syllable_count = 0
        haiku_line = 0
        for word in split:
            syllable_count += _count_syllables(word)
            if syllable_count == haiku_form[haiku_line]:
                haiku_line += 1
                if haiku_line >= len(haiku_form):
                    return True
            elif syllable_count > haiku_form[haiku_line]:
                return False

if __name__ == '__main__':
    print check_string('As the wind does blow Across the trees, I see the Buds blooming in May')
    print check_string('I walk across sand And find myself blistering In the hot, hot heat')<commit_msg>Working method to tell if line matches haiku syntax<commit_after>import simplejson as json
import sys, re

# load the cmu dict
try:
    cmu = json.load(open('cmu_dict.json'))
except:
    print "Converted CMU dict not found"
    sys.exit(0)

SubSyl = [
       'cial',
       'tia',
       'cius',
       'cious',
       'giu',              # belgium!
       'ion',
       'iou',
       'sia$',
       '.ely$',             # absolutely! (but not ely!)
      ]

AddSyl = [
       'ia',
       'riet',
       'dien',
       'iu',
       'io',
       'ii',
       '[aeiouym]bl$',     # -Vble, plus -mble
       '[aeiou]{3}',       # agreeable
       '^mc',
       'ism$',             # -isms
       '([^aeiouy])\1l$',  # middle twiddle battle bottle, etc.
       '[^l]lien',         # alien, salient [1]
           '^coa[dglx].',      # [2]
       '[^gq]ua[^auieo]',  # i think this fixes more than it breaks
       'dnt$',           # couldn't
      ]

def _guess_sy_count(word):
    """If we can't lookup the word, then guess its syllables count. This is
    (heavily) based on Greg Fast's Perl module Lingua::EN::Syllables. But
    the bugs are mine."""
    mungedword = re.sub('e$','',word.lower())
    splitword = re.split(r'[^aeiouy]+', mungedword)
    splitword = [ x for x in splitword if (x != '') ] # hmm
    syllables = 0
    for i in SubSyl:
        if re.search(i,mungedword):
            syllables -= 1
    for i in AddSyl:
        if re.search(i,mungedword):
            syllables += 1
    if len(mungedword) == 1: syllables =+ 1
    syllables += len(splitword)
    if syllables == 0: syllables = 1
    return syllables

def _count_syllables(word):
    if cmu.has_key(word):
        return cmu[word]
    else:
        return _guess_sy_count(word)

def check_string(to_check):

    haiku_form = [5,12,17]

    upper = to_check.upper()
    split = upper.split(' ')

    for count in haiku_form:
        syllable_count = 0
        haiku_line = 0
        for word in split:
            syllable_count += _count_syllables(word)
            if syllable_count == haiku_form[haiku_line]:
                haiku_line += 1
                if haiku_line >= len(haiku_form):
                    return True
            elif syllable_count > haiku_form[haiku_line]:
                return False

if __name__ == '__main__':
    print check_string('As the wind does blow Across the trees, I see the Buds blooming in May')
    print check_string('Itest walk across sand And find myself blistering In the hot, hot heat')<|endoftext|>


<commit_before>from distutils.command.bdist import bdist
import sys

if 'egg' not in bdist.format_commands:
    bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
    bdist.format_commands.append('egg')

del bdist, sys
<commit_msg>Update 'bdist' format addition to assume a single 'format_commands' as a dictionary, but fall back to the dual dict/list model for compatibility with stdlib.<commit_after>from distutils.command.bdist import bdist
import sys

if 'egg' not in bdist.format_commands:
    try:
        bdist.format_commands['egg'] = ('bdist_egg', "Python .egg file")
    except TypeError:
        # For backward compatibility with older distutils (stdlib)
        bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
        bdist.format_commands.append('egg')

del bdist, sys
<|endoftext|>


<commit_before>from sfepy.base.base import *
from sfepy.applications import SimpleApp, Application
from sfepy.fem import eval_term_op
from sfepy.fem.region import sort_by_dependency
from coefs_base import MiniAppBase

def insert_sub_reqs( reqs, levels, req_info ):
    """Recursively build all requirements in correct order."""
    all_reqs = []
##     print '>', levels, reqs
    for ii, req in enumerate( reqs ):
        try:
            rargs = req_info[req]
        except KeyError:
            raise ValueError('requirement "%s" is not defined!' % req)

        sub_reqs = rargs.get( 'requires', [] )
##         print '*', ii, req, sub_reqs

        if req in levels:
            raise ValueError('circular requirement "%s"!' % (req))

        if sub_reqs:
            levels.append( req )
            all_reqs.extend( insert_sub_reqs( sub_reqs, levels, req_info ) )
            levels.pop()

        if req in all_reqs:
            raise ValueError('circular requirement "%s"!' % (req))
        else:
            all_reqs.append( req )

##     print all_reqs
##     pause()
    return all_reqs

class HomogenizationEngine( SimpleApp ):

    def process_options( options ):
        get = options.get_default_attr

        coefs = get( 'coefs', None, 'missing "coefs" in options!' )
        requirements = get( 'requirements', None,
                            'missing "requirements" in options!' )

        save_format = get( 'save_format', 'vtk' )
        dump_format = get( 'dump_format', 'h5' )

        return Struct( **locals() )
    process_options = staticmethod( process_options )

    def __init__( self, problem, options,
                  volume = None, output_prefix = 'he:', **kwargs ):
        """Bypasses SimpleApp.__init__()!"""
        Application.__init__( self, problem.conf, options, output_prefix,
                              **kwargs )
        self.problem = problem
        self.setup_options()
        self.setup_output_info( self.problem, self.options )

        if volume is None:
            self.volume = eval_term_op( None, self.app_options.total_volume,
                                        self.problem )
        else:
            self.volume = volume

    def setup_options( self ):
        SimpleApp.setup_options( self )
        po = HomogenizationEngine.process_options
        self.app_options += po( self.conf.options )

    def compute_requirements( self, requirements, dependencies, store ):
        problem = self.problem

        opts = self.app_options
        req_info = getattr( self.conf, opts.requirements )

        requires = insert_sub_reqs( copy( requirements ), [], req_info )

        for req in requires:
            if req in dependencies and (dependencies[req] is not None):
                continue

            output( 'computing dependency %s...' % req )

            rargs = req_info[req]

            mini_app = MiniAppBase.any_from_conf( req, problem, rargs )
            mini_app.setup_output( save_format = opts.save_format,
                                   dump_format = opts.dump_format,
                                   post_process_hook = self.post_process_hook,
                                   file_per_var = opts.file_per_var )
            store( mini_app )

            dep = mini_app( data = dependencies )

            dependencies[req] = dep
            output( '...done' )

        return dependencies

    def call( self, ret_all = False ):
        problem = self.problem

        opts = self.app_options
        coef_info = getattr( self.conf, opts.coefs )

        is_store_filenames = coef_info.pop('filenames', None) is not None

        dependencies = {}
        save_names = {}
        dump_names = {}
        def store_filenames( app ):
            if not '(not_set)' in app.get_save_name_base():
                save_names[app.name] = app.get_save_name_base()
            if not '(not_set)' in app.get_dump_name_base():
                dump_names[app.name] = app.get_dump_name_base()

        def _get_parents(req_list):
            out = []
            for req_name in req_list:
                aux = req_name.split('.')
                if len(aux) == 2:
                    out.append(aux[1])
            return out

        # Some coefficients can require other coefficients - resolve theirorder
        # here.
        graph = {}
        for coef_name, cargs in coef_info.iteritems():
            if not coef_name in graph:
                graph[coef_name] = [0]

            requires = cargs.get('requires', [])
            for parent in _get_parents(requires):
                graph[coef_name].append(parent)
                requires.remove('c.' + parent)

        sorted_coef_names = sort_by_dependency(deepcopy(graph))
        ## print graph
        ## print sorted_coef_names

        coefs = Struct()
        for coef_name in sorted_coef_names:
            cargs = coef_info[coef_name]
            output( 'computing %s...' % coef_name )
            requires = cargs.get( 'requires', [] )

            self.compute_requirements( requires, dependencies, store_filenames )

            mini_app = MiniAppBase.any_from_conf( coef_name, problem, cargs )
            if len(graph[coef_name]) > 1:
                for name in graph[coef_name][1:]:
                    key = 'c.' + name
                    requires.append(key)
                    dependencies[key] = getattr(coefs, name)

            val = mini_app( self.volume, data = dependencies )
            setattr( coefs, coef_name, val )
            output( '...done' )

        # Store filenames of all requirements as a "coefficient".
        if is_store_filenames:
            coefs.save_names = save_names
            coefs.dump_names = dump_names

        if ret_all:
            return coefs, dependencies
        else:
            return coefs
<commit_msg>hom: clear equations before calling corrector or coefficient mini_app<commit_after>from sfepy.base.base import *
from sfepy.applications import SimpleApp, Application
from sfepy.fem.region import sort_by_dependency
from coefs_base import MiniAppBase

def insert_sub_reqs( reqs, levels, req_info ):
    """Recursively build all requirements in correct order."""
    all_reqs = []
##     print '>', levels, reqs
    for ii, req in enumerate( reqs ):
        try:
            rargs = req_info[req]
        except KeyError:
            raise ValueError('requirement "%s" is not defined!' % req)

        sub_reqs = rargs.get( 'requires', [] )
##         print '*', ii, req, sub_reqs

        if req in levels:
            raise ValueError('circular requirement "%s"!' % (req))

        if sub_reqs:
            levels.append( req )
            all_reqs.extend( insert_sub_reqs( sub_reqs, levels, req_info ) )
            levels.pop()

        if req in all_reqs:
            raise ValueError('circular requirement "%s"!' % (req))
        else:
            all_reqs.append( req )

##     print all_reqs
##     pause()
    return all_reqs

class HomogenizationEngine( SimpleApp ):

    def process_options( options ):
        get = options.get_default_attr

        coefs = get( 'coefs', None, 'missing "coefs" in options!' )
        requirements = get( 'requirements', None,
                            'missing "requirements" in options!' )

        save_format = get( 'save_format', 'vtk' )
        dump_format = get( 'dump_format', 'h5' )

        return Struct( **locals() )
    process_options = staticmethod( process_options )

    def __init__( self, problem, options,
                  volume = None, output_prefix = 'he:', **kwargs ):
        """Bypasses SimpleApp.__init__()!"""
        Application.__init__( self, problem.conf, options, output_prefix,
                              **kwargs )
        self.problem = problem
        self.setup_options()
        self.setup_output_info( self.problem, self.options )

        if volume is None:
            self.volume = eval_term_op( None, self.app_options.total_volume,
                                        self.problem )
        else:
            self.volume = volume

    def setup_options( self ):
        SimpleApp.setup_options( self )
        po = HomogenizationEngine.process_options
        self.app_options += po( self.conf.options )

    def compute_requirements( self, requirements, dependencies, store ):
        problem = self.problem

        opts = self.app_options
        req_info = getattr( self.conf, opts.requirements )

        requires = insert_sub_reqs( copy( requirements ), [], req_info )

        for req in requires:
            if req in dependencies and (dependencies[req] is not None):
                continue

            output( 'computing dependency %s...' % req )

            rargs = req_info[req]

            mini_app = MiniAppBase.any_from_conf( req, problem, rargs )
            mini_app.setup_output( save_format = opts.save_format,
                                   dump_format = opts.dump_format,
                                   post_process_hook = self.post_process_hook,
                                   file_per_var = opts.file_per_var )
            store( mini_app )

            problem.clear_equations()
            dep = mini_app( data = dependencies )

            dependencies[req] = dep
            output( '...done' )

        return dependencies

    def call( self, ret_all = False ):
        problem = self.problem

        opts = self.app_options
        coef_info = getattr( self.conf, opts.coefs )

        is_store_filenames = coef_info.pop('filenames', None) is not None

        dependencies = {}
        save_names = {}
        dump_names = {}
        def store_filenames( app ):
            if not '(not_set)' in app.get_save_name_base():
                save_names[app.name] = app.get_save_name_base()
            if not '(not_set)' in app.get_dump_name_base():
                dump_names[app.name] = app.get_dump_name_base()

        def _get_parents(req_list):
            out = []
            for req_name in req_list:
                aux = req_name.split('.')
                if len(aux) == 2:
                    out.append(aux[1])
            return out

        # Some coefficients can require other coefficients - resolve theirorder
        # here.
        graph = {}
        for coef_name, cargs in coef_info.iteritems():
            if not coef_name in graph:
                graph[coef_name] = [0]

            requires = cargs.get('requires', [])
            for parent in _get_parents(requires):
                graph[coef_name].append(parent)
                requires.remove('c.' + parent)

        sorted_coef_names = sort_by_dependency(deepcopy(graph))
        ## print graph
        ## print sorted_coef_names

        coefs = Struct()
        for coef_name in sorted_coef_names:
            cargs = coef_info[coef_name]
            output( 'computing %s...' % coef_name )
            requires = cargs.get( 'requires', [] )

            self.compute_requirements( requires, dependencies, store_filenames )

            mini_app = MiniAppBase.any_from_conf( coef_name, problem, cargs )
            if len(graph[coef_name]) > 1:
                for name in graph[coef_name][1:]:
                    key = 'c.' + name
                    requires.append(key)
                    dependencies[key] = getattr(coefs, name)

            problem.clear_equations()
            val = mini_app( self.volume, data = dependencies )
            setattr( coefs, coef_name, val )
            output( '...done' )

        # Store filenames of all requirements as a "coefficient".
        if is_store_filenames:
            coefs.save_names = save_names
            coefs.dump_names = dump_names

        if ret_all:
            return coefs, dependencies
        else:
            return coefs
<|endoftext|>