<commit_before>import copy
import json
import logging
from datetime import datetime

from cryptography.fernet import Fernet
from sqlitedict import SqliteDict

from mirror.event_bus import Event
from mirror.paths import ROOTDIR

_logger = logging.getLogger(__name__)


class PluginContext:
    """Services provided to plugins.

    Plugins are provided with an instance of this class and do not create one
    themselves.
    """

    def __init__(self, plugin_name, event_bus) -> None:
        self.plugin_name = plugin_name
        self._event_bus = event_bus
        self.db = PluginDatabase(plugin_name)

    async def post_event(self, name: str, data: dict) -> None:
        """Post an event that is available to client-side JavaScript.

        :param name: Name of the event (see notes below).
        :param data: Data sent with the event. Send {} if there is no data.

        The plugin name is automatically used to namespace all events as they appear on
        the client side. For example:

        `myplugin.myeventname`

        Some metadata keys are also automatically added to the event data:

        _source: The name of the plugin
        _time: When the event was raised
        """
        if data is None:
            return
        data = copy.deepcopy(data)  # Copy data to avoid caller side-effects.
        full_name = f"{self.plugin_name}.{name}"
        data["_source"] = self.plugin_name
        data["_time"] = datetime.now().isoformat()
        await self._event_bus.post(Event(name=full_name, data=data))

    _connectivity_score = 0

    @property
    def is_connected(self):
        """Whether the network is connected."""
        return PluginContext._connectivity_score >= 0

    def vote_connected(self):
        """Allows a plugin to vote that the network is connected."""
        score = min(PluginContext._connectivity_score + 1, 10)
        PluginContext._connectivity_score = score
        _logger.info(
            "%s votes connected; score: %s",
            self.plugin_name,
            score,
        )

    def vote_disconnected(self, cause: Exception):
        """Allows a plugin to vote that the network is disconnected."""
        score = max(PluginContext._connectivity_score - 1, -10)
        _logger.info(
            "%s votes disconnected because of %s; score: %s",
            self.plugin_name,
            cause,
            score,
        )

<commit_msg>Fix bug preventing offline detection<commit_after>import copy
import json
import logging
from datetime import datetime

from cryptography.fernet import Fernet
from sqlitedict import SqliteDict

from mirror.event_bus import Event
from mirror.paths import ROOTDIR

_logger = logging.getLogger(__name__)


class PluginContext:
    """Services provided to plugins.

    Plugins are provided with an instance of this class and do not create one
    themselves.
    """

    def __init__(self, plugin_name, event_bus) -> None:
        self.plugin_name = plugin_name
        self._event_bus = event_bus
        self.db = PluginDatabase(plugin_name)

    async def post_event(self, name: str, data: dict) -> None:
        """Post an event that is available to client-side JavaScript.

        :param name: Name of the event (see notes below).
        :param data: Data sent with the event. Send {} if there is no data.

        The plugin name is automatically used to namespace all events as they appear on
        the client side. For example:

        `myplugin.myeventname`

        Some metadata keys are also automatically added to the event data:

        _source: The name of the plugin
        _time: When the event was raised
        """
        if data is None:
            return
        data = copy.deepcopy(data)  # Copy data to avoid caller side-effects.
        full_name = f"{self.plugin_name}.{name}"
        data["_source"] = self.plugin_name
        data["_time"] = datetime.now().isoformat()
        await self._event_bus.post(Event(name=full_name, data=data))

    _connectivity_score = 0

    @property
    def is_connected(self):
        """Whether the network is connected."""
        return PluginContext._connectivity_score >= 0

    def vote_connected(self):
        """Allows a plugin to vote that the network is connected."""
        score = min(PluginContext._connectivity_score + 1, 10)
        PluginContext._connectivity_score = score
        _logger.info(
            "%s votes connected; score: %s",
            self.plugin_name,
            score,
        )

    def vote_disconnected(self, cause: Exception):
        """Allows a plugin to vote that the network is disconnected."""
        score = max(PluginContext._connectivity_score - 1, -10)
        PluginContext._connectivity_score = score
        _logger.info(
            "%s votes disconnected because of %s; score: %s",
            self.plugin_name,
            cause,
            score,
        )


{'fraction_non_alphanumeric': 0.07913522333265348, 'fraction_numerical': 0.0032633081786661226, 'mean_word_length': 2.4804826117814054, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4608685', 'n_tokens_mistral': 1334, 'n_tokens_neox': 1282, 'n_words': 472}