#!/usr/bin/env python
# -*- coding: UTF-8 -*-
""" Module callbacks: This module contains objects for dealing with
customized callbacks in Mari."""
import logging
import mari
[docs]class Publisher(object):
"""
This class creates a watcher that can be subscribed to in order to perform
the necessary callbacks.
"""
def __init__(self):
"""
The constructor.
:return: ``None``
"""
self.logger = logging.getLogger(__name__)
self.__subscribers = []
[docs] def register_subscriber(self, subscriber):
"""
This method adds a subscriber.
:param subscriber: ``Subscriber`` subscriber object.
"""
self.__subscribers.append(subscriber)
[docs] def notify(self, reason=None, *args, **kwargs):
"""
This method notifies all currently subscribed observers.
:param reason: ``str`` message indicating what the reason for the
status change is.
"""
for subscriber in self.__subscribers:
subscriber.update(reason, *args, **kwargs)
[docs]class Subscriber(object):
"""
This base class creates a *Subscriber* to the *Publisher* object and watches
for changes.
"""
def __init__(self, publisher):
"""
The constructor.
:param publisher: ``Publisher`` publisher object.
:return: ``None``
"""
self.logger = logging.getLogger(__name__)
publisher.register_subscriber(self)
[docs] def update(self, reason, *args, **kwargs):
"""
This method is called on the *Subscriber* object whenever the publisher
is updated. Should be overloaded in order to perform additional actions
once the publisher has received a change in the status.
:param reason: ``str`` message indicating what the reason for the
status change is.
:return: ``None``
"""
self.logger.debug('Updating due to: {0}'.format(reason))
raise NotImplementedError(
'update() needs to be implemented in your subscriber!!!'
)
[docs]class ProjectChangedPublisher(Publisher):
"""
This class publishes project change events (opening/closing/switching) in
Mari and notifies all subscribers to it as necessary.
"""
def __init__(self):
super(ProjectChangedPublisher, self).__init__()
mari.utils.connect(
mari.projects.opened,
lambda: self.notify(reason='New project opened', event='project_opened')
)
mari.utils.connect(
mari.projects.closed,
lambda: self.notify(reason='Project closed', event='project_closed')
)
[docs]class ProjectChangedSubscriber(Subscriber):
"""
This class subscribes to project change events (opening/closing/switching)
in Mari and performs actions as necessary.
"""
def __init__(self, publisher):
"""
The constructor.
:param publisher:
:return:
"""
super(ProjectChangedSubscriber, self).__init__(publisher)
self.logger = logging.getLogger(__name__)
publisher.register_subscriber(self)
[docs] def update(self, reason, *args, **kwargs):
"""
This method makes all necessary changes when a project has changed its
state in Mari.
:param reason:
:param args:
:param kwargs:
:return:
"""
if 'event' not in kwargs.keys():
self.logger.error('### Event was not specified!!!')
return
elif kwargs.get('event') == 'project_opened':
self.project_opened()
elif kwargs.get('event') == 'project_closed':
self.project_closed()
else:
self.logger.event(
'### Unrecognized event: {0}'.format(kwargs.get('event'))
)
[docs] def project_opened(self):
"""
This method is run whenever a new project is opened in Mari.
"""
raise NotImplementedError('project_opened() must be implemented!')
[docs] def project_closed(self):
"""
This method is run whenever a current project is closed in Mari.
"""
raise NotImplementedError('project_closed() must be implemented!')