<commit_before># Copyright (C) 2020 OpenMotics BV
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
Base Controller
"""
from __future__ import absolute_import

import logging
import time

from gateway.daemon_thread import DaemonThread
from gateway.hal.master_controller import MasterController
from gateway.hal.master_event import MasterEvent
from gateway.models import BaseModel
from gateway.pubsub import PubSub
from ioc import INJECTED, Inject
from serial_utils import CommunicationTimedOutException

if False:  # MYPY
    from typing import Optional, Callable, Type, List
    from gateway.maintenance_controller import MaintenanceController

logger = logging.getLogger("openmotics")


class SyncStructure(object):
    def __init__(self, orm_model, name, skip=None):  # type: (Type[BaseModel], str, Optional[Callable[[BaseModel], bool]]) -> None
        self.orm_model = orm_model  # type: Type[BaseModel]
        self.name = name  # type: str
        self.skip = skip  # type: Optional[Callable[[BaseModel], bool]]


class BaseController(object):

    SYNC_STRUCTURES = None  # type: Optional[List[SyncStructure]]

    @Inject
    def __init__(self, master_controller, maintenance_controller=INJECTED, pubsub=INJECTED, sync_interval=900):
        # type: (MasterController, MaintenanceController, PubSub, float) -> None
        self._master_controller = master_controller
        self._maintenance_controller = maintenance_controller
        self._pubsub = pubsub
        self._sync_orm_thread = None  # type: Optional[DaemonThread]
        self._sync_orm_interval = sync_interval
        self._sync_running = False

        self._pubsub.subscribe_master_events(PubSub.MasterTopics.MASTER, self._handle_master_event)
        self._pubsub.subscribe_master_events(PubSub.MasterTopics.MAINTENANCE, self._handle_master_event)

    def _handle_master_event(self, master_event):
        # type: (MasterEvent) -> None
        if master_event.type in [MasterEvent.Types.EEPROM_CHANGE,
                                 MasterEvent.Types.MAINTENANCE_EXIT,
                                 MasterEvent.Types.MODULE_DISCOVERY]:
            self.request_sync_orm()

    def start(self):
        self._sync_orm_thread = DaemonThread(name='ORM syncer for {0}'.format(self.__class__.__name__),
                                             target=self._sync_orm,
                                             interval=self._sync_orm_interval,
                                             delay=300)
        self._sync_orm_thread.start()

    def stop(self):
        if self._sync_orm_thread is not None:
            self._sync_orm_thread.stop()

    def request_sync_orm(self):<commit_msg>fixup! use pubsub messages for master / base controllers<commit_after># Copyright (C) 2020 OpenMotics BV
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
Base Controller
"""
from __future__ import absolute_import

import logging
import time

from gateway.daemon_thread import DaemonThread
from gateway.hal.master_controller import MasterController
from gateway.hal.master_event import MasterEvent
from gateway.models import BaseModel
from gateway.pubsub import PubSub
from ioc import INJECTED, Inject
from serial_utils import CommunicationTimedOutException

if False:  # MYPY
    from typing import Optional, Callable, Type, List
    from gateway.maintenance_controller import MaintenanceController

logger = logging.getLogger("openmotics")


class SyncStructure(object):
    def __init__(self, orm_model, name, skip=None):  # type: (Type[BaseModel], str, Optional[Callable[[BaseModel], bool]]) -> None
        self.orm_model = orm_model  # type: Type[BaseModel]
        self.name = name  # type: str
        self.skip = skip  # type: Optional[Callable[[BaseModel], bool]]


class BaseController(object):

    SYNC_STRUCTURES = None  # type: Optional[List[SyncStructure]]

    @Inject
    def __init__(self, master_controller, maintenance_controller=INJECTED, pubsub=INJECTED, sync_interval=900):
        # type: (MasterController, MaintenanceController, PubSub, float) -> None
        self._master_controller = master_controller
        self._maintenance_controller = maintenance_controller
        self._pubsub = pubsub
        self._sync_orm_thread = None  # type: Optional[DaemonThread]
        self._sync_orm_interval = sync_interval
        self._sync_running = False

        self._pubsub.subscribe_master_events(PubSub.MasterTopics.EEPROM, self._handle_master_event)
        self._pubsub.subscribe_master_events(PubSub.MasterTopics.MASTER, self._handle_master_event)

    def _handle_master_event(self, master_event):
        # type: (MasterEvent) -> None
        if master_event.type in [MasterEvent.Types.EEPROM_CHANGE,
                                 MasterEvent.Types.MODULE_DISCOVERY]:
            self.request_sync_orm()

    def start(self):
        self._sync_orm_thread = DaemonThread(name='ORM syncer for {0}'.format(self.__class__.__name__),
                                             target=self._sync_orm,
                                             interval=self._sync_orm_interval,
                                             delay=300)
        self._sync_orm_thread.start()

    def stop(self):
        if self._sync_orm_thread is not None:
            self._sync_orm_thread.stop()

    def request_sync_orm(self):
{'fraction_non_alphanumeric': 0.07445344748509403, 'fraction_numerical': 0.003669163736431738, 'mean_word_length': 3.2370466321243523, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 15, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2205963', 'n_tokens_mistral': 1777, 'n_tokens_neox': 1725, 'n_words': 525}