class WeakCollection(object):
    def __init__(self, seq=tuple()):
        self._d = WeakValueDictionary()
        for item in seq:
            self.add(item)
    def add(self, item):
        self._d[id(item)] = item
    def remove(self, item):
        del self._id[id(item)]
    def __iter__(self):
        for iid, item in self._d.iteritems():
            yield item
Exemple #2
0
class Node(NanoResource):
    context_attributes = ['name', 'realm', 'address', 'node_monitor']

    def __init__(self, name, realm=None, address=None, node_monitor=None,
                 monitoring_groups=None, **kwargs):
        self.name = name
        self.realm = realm
        self.address = address or name
        self.node_monitor = node_monitor
        self.monitoring_groups = WeakValueDictionary()
        self._tasks = []
        if monitoring_groups:
            for group in monitoring_groups:
                if not isinstance(group, MonitoringGroup):
                    try:
                        group = MonitoringGroup.registry[group]
                    except KeyError:
                        logger.error("Unable to find MonitoringGroup '%s' "
                                     "in registry, skipping." % (group))
                group.add_node(self)

        super(Node, self).__init__(name, **kwargs)

    def build_context(self, monitoring_group, monitor):
        context = {}
        for obj in (monitoring_group, self, monitor):
            context = obj._build_context(context)
        return context

    @property
    def monitors(self):
        if self._tasks:
            return self._tasks
        for group_name, group in self.monitoring_groups.iteritems():
            for monitor_name, monitor in group.monitors.iteritems():
                self._tasks.append(self.build_context(group, monitor))
        return self._tasks
class ModulePanel(QtWidgets.QDockWidget):
    def __init__(self, parent=None):
        super(ModulePanel, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setObjectName("mop_settings_panel")
        self.setWindowTitle("Module Panel")

        self._module_widgets = WeakValueDictionary()
        self._modified_fields = set()
        self._initial_values = {}

        self.setWidget(QtWidgets.QWidget())

        self.settings_group = QtWidgets.QGroupBox("Settings")
        self.form = QtWidgets.QFormLayout()
        self.apply_button = QtWidgets.QPushButton("Apply")
        self.reset_button = QtWidgets.QPushButton("Reset")

        self.actions_group = QtWidgets.QGroupBox("Actions")
        self.mirror_button = QtWidgets.QPushButton("Mirror")
        self.update_mirror_button = QtWidgets.QPushButton("Update Mirror")
        self.duplicate_button = QtWidgets.QPushButton("Duplicate")
        self.delete_button = QtWidgets.QPushButton("Delete")

        layout = QtWidgets.QVBoxLayout()
        self.widget().setLayout(layout)

        layout.addWidget(self.settings_group)
        layout.addStretch()
        layout.addWidget(self.actions_group)

        settings_layout = QtWidgets.QVBoxLayout()
        self.settings_group.setLayout(settings_layout)
        settings_layout.addLayout(self.form)

        settings_actions_layout = QtWidgets.QHBoxLayout()
        settings_layout.addLayout(settings_actions_layout)

        settings_actions_layout.addWidget(self.apply_button)
        settings_actions_layout.addWidget(self.reset_button)

        actions_layout = QtWidgets.QVBoxLayout()
        self.actions_group.setLayout(actions_layout)
        actions_layout.addWidget(self.mirror_button)
        actions_layout.addWidget(self.update_mirror_button)
        actions_layout.addWidget(self.duplicate_button)
        actions_layout.addWidget(self.delete_button)

        self.apply_button.hide()
        self.reset_button.hide()
        self.mirror_button.hide()
        self.update_mirror_button.hide()
        self.duplicate_button.hide()
        self.delete_button.hide()

        self.apply_button.released.connect(self._update_module)
        self.reset_button.released.connect(self._update_ui)
        self.mirror_button.released.connect(self._mirror_module)
        self.update_mirror_button.released.connect(self._update_mirror)
        self.duplicate_button.released.connect(self._duplicate_module)
        self.delete_button.released.connect(self._delete_module)

        subscribe("selected-modules-changed", self._on_selection_changed)

    def closeEvent(self, event):
        unsubscribe("selected-modules-changed", self._on_selection_changed)

    def _on_selection_changed(self, modules):
        """Update the module to edit.

        ``modules`` argument is a :class:`list` of
        :class:`mop.core.module.RigModule` and/or :class:`str`
        instances.

        :param pointer: Data to the selected module.
                        It is a list of modules and/or joints.
        :type pointer: list
        """
        if not modules:
            return
        self.modules = modules
        self._update_ui()

    def _on_field_edited(self, widget, *args):
        label = self.form.labelForField(widget)
        if widget.get() != self._initial_values[widget]:
            self._modified_fields.add(widget)
            label.setStyleSheet("font-weight: bold")
        else:
            self._modified_fields.remove(widget)
            label.setStyleSheet("")

        if self._modified_fields:
            self.apply_button.setEnabled(True)
            self.reset_button.setEnabled(True)
        else:
            self.apply_button.setEnabled(False)
            self.reset_button.setEnabled(False)

    def _update_module(self):
        """Update the Maya module."""
        if not self.modules:
            return

        modified_fields = defaultdict(dict)
        for module in self.modules:
            old_name = module.node_name
            for name, widget in self._module_widgets.iteritems():
                if widget not in self._modified_fields:
                    continue
                field = getattr(module, name)
                old_value = field.get()
                value = widget.get()
                field.set(value)
                label = self.form.labelForField(widget)
                label.setStyleSheet("")
                self._initial_values[widget] = value
                modified_fields[module][name] = (old_value, value)
            module.update()
            new_name = module.node_name
            if new_name != old_name:
                modified_fields[module]["node_name"] = (old_name, new_name)

        self.apply_button.setEnabled(False)
        self.reset_button.setEnabled(False)
        self._modified_fields.clear()

        publish("modules-updated", modified_fields)

    def _delete_module(self):
        """Delete the selected module."""
        if not self.modules:
            return
        button = QtWidgets.QMessageBox.warning(
            self,
            "mop - Delete Module",
            "You are about to delete %d module(s). Continue ?" %
            len(self.modules),
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
        )
        if button != QtWidgets.QMessageBox.Yes:
            return
        rig = Rig()
        modules = self.modules[:]
        for module in self.modules:
            if module.name.get() == "root":
                logger.warning("Cannot delete root module.")
                modules.remove(module)
                continue
            rig.delete_module(module.node_name)
        publish("modules-deleted", modules)

    def _duplicate_module(self):
        """Duplicate the selected module."""
        if not self.modules:
            return
        rig = Rig()
        new_modules = []
        for module in self.modules:
            new_module = rig.duplicate_module(module)
            new_modules.append(new_module)

        publish("modules-created", new_modules)

    @undoable
    def _mirror_module(self):
        if not self.modules:
            return
        rig = Rig()
        new_modules = []
        for module in self.modules:
            new_module = rig.mirror_module(module)
            if new_module is not None:
                new_modules.append(new_module)

        publish("modules-created", new_modules)

    @undoable
    def _update_mirror(self):
        if not self.modules:
            return
        for module in self.modules:
            mirror_mod = module.module_mirror
            if not mirror_mod:
                continue
            if mirror_mod in self.modules:
                self.modules.remove(mirror_mod)
            module.update_mirror()

    def _update_ui(self):
        self._modified_fields.clear()
        self._initial_values.clear()
        clear_layout(self.form)
        if not self.modules:
            self.apply_button.hide()
            self.reset_button.hide()
            self.mirror_button.hide()
            self.update_mirror_button.hide()
            self.duplicate_button.hide()
            self.delete_button.hide()
            return

        # If one of the module is built, disable actions.
        is_built = False
        for module in self.modules:
            if module.is_built.get():
                is_built = True

        if is_built:
            self.mirror_button.setEnabled(False)
            self.update_mirror_button.setEnabled(False)
            self.duplicate_button.setEnabled(False)
            self.delete_button.setEnabled(False)
        else:
            self.mirror_button.setEnabled(True)
            self.update_mirror_button.setEnabled(True)
            self.duplicate_button.setEnabled(True)
            self.delete_button.setEnabled(True)

        # Enable apply and reset button only when a field has
        # been modified.
        self.apply_button.setEnabled(False)
        self.reset_button.setEnabled(False)
        self.apply_button.show()
        self.reset_button.show()
        self.mirror_button.show()
        self.update_mirror_button.show()
        self.duplicate_button.show()
        self.delete_button.show()

        # Only show fields shared by all selected modules.
        field_names = set([f.name for f in self.modules[-1].fields])
        for other in self.modules[:-1]:
            other_names = set([f.name for f in other.fields])
            field_names = field_names.intersection(other_names)

        # Filter out fields that must be unique, so users cannot
        # edit them on multiple modules at once.
        for field in self.modules[-1].fields:
            if not field.unique:
                continue
            if field.name in field_names and len(self.modules) > 1:
                field_names.remove(field.name)

        fields = [f for f in self.modules[-1].fields if f.name in field_names]
        ordered_fields = sorted(fields, key=attrgetter("gui_order"))
        for field in ordered_fields:
            if not field.displayable:
                continue

            class_name = field.__class__.__name__
            widget_data = map_field_to_widget.get(
                class_name, map_field_to_widget["StringField"])
            widget = widget_data(field)
            if field.tooltip:
                widget.setToolTip(field.tooltip)
            value = getattr(self.modules[-1], field.name).get()
            widget.set(value)
            self._initial_values[widget] = value

            self._module_widgets[field.name] = widget
            widget.signal().connect(partial(self._on_field_edited, widget))

            self.form.addRow(field.display_name, widget)

            if not field.editable or is_built:
                widget.setEnabled(False)
Exemple #4
0
class Data(object):
    """
    Class to handle Data, especailly Users:
      Data[item] -> returns a item object.
    If item is a string, it is case insensitive, but item can be anything.
    The item is stored as "handle" into the Item object, probably often
    just flying around, sometimes meaning you have double entries (with db).
      
    You can change self.main_key to change the default item to a name 
    different from 'handle'. For example the ID in the database, or whatever.
      
    AS USER IS THE MAIN INTEREST, ALL HELP MAY REFER TO Users==Data
    and User == Item!
    
    Other things (ie, users.online) are added from outside.
      
    NOTES:
        o Use Registered functions to add functionality to user class.
           The registered function can change the items value by directly
           editing the User.items dictionary.
        o Registered functions are executed in the order that they are
           gotten. Classes ones are executed before Instance ones, so that
           they could modify the value before the instance thinks it changed.
           Instance ones _will_ also be executed if old == new.
    
    TIPS:
        o Instead of registering say "rating" which would be set when a
           function parsed the finger of a user, have it set
           "finger_update" = time.time() and register to that. That way you
           get notified even if the rating does not change AND always know
           when it was last updated.
        o For the same example, you might have a loader regestration for your
           database backend. The status module will set the items, but if a
           user is not connected, he does not have it set, so that loader
           gets called when you cannot get it through FICS. Yes, that means
           that you will need the dummy "finger_update" to force a reload
           through the finger function. (Of course this is rather
           hypethetical, afterall finger is always more up to date ;))
           
    Maybe the buffer should be improved ...
    """

    def __init__(self, main_key='handle', buffer_size = 20):
        # Define a dummy class and self.Item to make sure that each Users class
        # has its own child User class.
        class Items(_Item):
            _on_update = {}
            _loader = {}

        self.main_key = main_key
        Items.main_key = main_key
        self.Item = Items

        # Buffer to make sure we don't discard items that often ...
        # As long as the item has a reference stored here or ANYWHERE else
        # he will not be discarted.
        if buffer_size < 1:
            self._buffer = None
        else:
            self._buffer = [None]*buffer_size

        # dictionary mapping item_name -> item object. This is a WEAKREF!
        from weakref import WeakValueDictionary
        self._loaded_items = WeakValueDictionary()
    

    def register(self, item, function, persistent=True, loader=False):
        """
        register(item, function, persistent=True)
        Register a function to be executed when item gets updated next time.
        Multiple functions can be registered, all will update when this happens.
        NOTES:
            o Function must take (item_object, item_name, old, new) as arguments.
            o Do not mass use this, otherwise its probably better to
               add it to the _item_set()/_item_load() special function.
            o loader keyword: The funciton is not called on set, but on a
               get event. (First time load). Only one function can be
               assigned. quietly overwrites all existing ones.
               Always persistent. The function MUST set the item.
        This will register for ALL items.
        """
        if loader == True:
            self.Item._loader[item] = function
            return
            
        if self.Item._on_update.has_key(item):
            self.Item._on_update[item].append([function, persistent])
            return
        self.Item._on_update[item] = [[function, persistent]]

    
    def unregister(self, item, function, loader):
        """
        Unregister a function again ...
        """
        if loader:
            del self.Item._loader[item]
            return
        try:
            self.Item._on_update[item].remove([function, True])
        except ValueError:
            self.Item._on_update[item].remove([function, False])


    def __getitem__(self, handle):
        try:
            ident = handle.lower()
        except AttributeError:
            ident = handle
        if not self._loaded_items.has_key(ident):
            return self._load(handle)
        #print handle, ident, self._loaded_items[ident].items
        return self._loaded_items[ident]


    def _load(self, handle):
        new_item = self.Item(handle)
        try:
            ident = handle.lower()
        except AttributeError:
            ident = handle
        
        self._loaded_items[ident] = new_item
        if self._buffer is not None:
            del self._buffer[0]
            self._buffer += [new_item]
        return new_item        


    def iteritems(self):
        """Iterator over all stored items.
        """
        return self._loaded_items.iteritems()
        
    def iterkeys(self):
        """Iterator over all stored keys.
        """
        return self._loaded_items.iterkeys()

    def itervalues(self):
        """Iterator over all stored items.
        """
        return self._loaded_items.itervalues()

    def __iter__(self):
        return self._loaded_items.__iter__()
Exemple #5
0
class Data(object):
    """
    Class to handle Data, especailly Users:
      Data[item] -> returns a item object.
    If item is a string, it is case insensitive, but item can be anything.
    The item is stored as "handle" into the Item object, probably often
    just flying around, sometimes meaning you have double entries (with db).
      
    You can change self.main_key to change the default item to a name 
    different from 'handle'. For example the ID in the database, or whatever.
      
    AS USER IS THE MAIN INTEREST, ALL HELP MAY REFER TO Users==Data
    and User == Item!
    
    Other things (ie, users.online) are added from outside.
      
    NOTES:
        o Use Registered functions to add functionality to user class.
           The registered function can change the items value by directly
           editing the User.items dictionary.
        o Registered functions are executed in the order that they are
           gotten. Classes ones are executed before Instance ones, so that
           they could modify the value before the instance thinks it changed.
           Instance ones _will_ also be executed if old == new.
    
    TIPS:
        o Instead of registering say "rating" which would be set when a
           function parsed the finger of a user, have it set
           "finger_update" = time.time() and register to that. That way you
           get notified even if the rating does not change AND always know
           when it was last updated.
        o For the same example, you might have a loader regestration for your
           database backend. The status module will set the items, but if a
           user is not connected, he does not have it set, so that loader
           gets called when you cannot get it through FICS. Yes, that means
           that you will need the dummy "finger_update" to force a reload
           through the finger function. (Of course this is rather
           hypethetical, afterall finger is always more up to date ;))
           
    Maybe the buffer should be improved ...
    """
    def __init__(self, main_key='handle', buffer_size=20):
        # Define a dummy class and self.Item to make sure that each Users class
        # has its own child User class.
        class Items(_Item):
            _on_update = {}
            _loader = {}

        self.main_key = main_key
        Items.main_key = main_key
        self.Item = Items

        # Buffer to make sure we don't discard items that often ...
        # As long as the item has a reference stored here or ANYWHERE else
        # he will not be discarted.
        if buffer_size < 1:
            self._buffer = None
        else:
            self._buffer = [None] * buffer_size

        # dictionary mapping item_name -> item object. This is a WEAKREF!
        from weakref import WeakValueDictionary
        self._loaded_items = WeakValueDictionary()

    def register(self, item, function, persistent=True, loader=False):
        """
        register(item, function, persistent=True)
        Register a function to be executed when item gets updated next time.
        Multiple functions can be registered, all will update when this happens.
        NOTES:
            o Function must take (item_object, item_name, old, new) as arguments.
            o Do not mass use this, otherwise its probably better to
               add it to the _item_set()/_item_load() special function.
            o loader keyword: The funciton is not called on set, but on a
               get event. (First time load). Only one function can be
               assigned. quietly overwrites all existing ones.
               Always persistent. The function MUST set the item.
        This will register for ALL items.
        """
        if loader == True:
            self.Item._loader[item] = function
            return

        if self.Item._on_update.has_key(item):
            self.Item._on_update[item].append([function, persistent])
            return
        self.Item._on_update[item] = [[function, persistent]]

    def unregister(self, item, function, loader):
        """
        Unregister a function again ...
        """
        if loader:
            del self.Item._loader[item]
            return
        try:
            self.Item._on_update[item].remove([function, True])
        except ValueError:
            self.Item._on_update[item].remove([function, False])

    def __getitem__(self, handle):
        try:
            ident = handle.lower()
        except AttributeError:
            ident = handle
        if not self._loaded_items.has_key(ident):
            return self._load(handle)
        #print handle, ident, self._loaded_items[ident].items
        return self._loaded_items[ident]

    def _load(self, handle):
        new_item = self.Item(handle)
        try:
            ident = handle.lower()
        except AttributeError:
            ident = handle

        self._loaded_items[ident] = new_item
        if self._buffer is not None:
            del self._buffer[0]
            self._buffer += [new_item]
        return new_item

    def iteritems(self):
        """Iterator over all stored items.
        """
        return self._loaded_items.iteritems()

    def iterkeys(self):
        """Iterator over all stored keys.
        """
        return self._loaded_items.iterkeys()

    def itervalues(self):
        """Iterator over all stored items.
        """
        return self._loaded_items.itervalues()

    def __iter__(self):
        return self._loaded_items.__iter__()
Exemple #6
0
# #         d['c'] = c
#     print 'i', i.key
#     print 'i', dir(i)


min_info = {}
weakdict = WeakValueDictionary()

for k, v in {'a': 1, 'b': 0, 'c': 3}.iteritems():
    inst = A(v)
    min_info[k] = inst
    weakdict[k] = inst

print 'min_info', min_info
print 'weakdict', [x() for x in weakdict.itervaluerefs()]
print 'weakdict', weakdict.iteritems()

for x in weakdict.itervaluerefs():
    print 'x', dir(weakdict.itervaluerefs())
    

# 10
# del a                       # удалить одну ссылку
# gc.collect()                # произвести сборку мусора
# 0
# d['primary']                # запись была автоматически удалена
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#     d['primary']
#   File "C:/python31/lib/weakref.py", line 46, in __getitem__
#     o = self.data[key]()