<commit_before>import logging
from datetime import timedelta

from django.conf import settings
from django.template.loader import render_to_string

from allauth.account.models import EmailAddress

from InvenTree.helpers import inheritors
from common.models import NotificationEntry, NotificationMessage
import InvenTree.tasks


logger = logging.getLogger('inventree')


# region notification classes
# region base classes
class NotificationMethod:
    METHOD_NAME = ''
    CONTEXT_BUILTIN = ['name', 'message', ]
    CONTEXT_EXTRA = []

    def __init__(self, obj, entry_name, targets, context) -> None:
        # Check if a sending fnc is defined
        if (not hasattr(self, 'send')) and (not hasattr(self, 'send_bulk')):
            raise NotImplementedError('A NotificationMethod must either define a `send` or a `send_bulk` method')

        # No method name is no good
        if self.METHOD_NAME in ('', None):
            raise NotImplementedError(f'The NotificationMethod {self.__class__} did not provide a METHOD_NAME')

        # Define arguments
        self.obj = obj
        self.entry_name = entry_name
        self.targets = targets
        self.context = self.check_context(context)

        # Gather recipients
        self.recipients = self.get_recipients()

    def check_context(self, context):
        def check(ref, obj):
            # the obj is not accesible so we are on the end
            if not isinstance(obj, (list, dict, tuple, )):
                return ref

            # check if the ref exsists
            if isinstance(ref, str):
                if not obj.get(ref):
                    return ref
                return False

            # nested
            elif isinstance(ref, (tuple, list)):
                if len(ref) == 1:
                    return check(ref[0], obj)
                ret = check(ref[0], obj)
                if ret:
                    return ret
                return check(ref[1:], obj[ref[0]])

            # other cases -> raise
            raise NotImplementedError('This type can not be used as a context reference')

        missing = []
        for item in (*self.CONTEXT_BUILTIN, *self.CONTEXT_EXTRA):
            ret = check(item, context)
            if ret:
                missing.append(ret)

        if missing:
            raise NotImplementedError(f'The `context` is missing the following items:\n{missing}')

        return context

    def get_recipients(self):
        raise NotImplementedError('The `get_recipients` method must be implemented!')

    def setup(self):
        return True

    # def send(self, receiver)
    # def send_bulk(self)

    def cleanup(self):
        return True


class SingleNotificationMethod(NotificationMethod):
    def send(self, receiver):
        raise NotImplementedError('The `send` method must be overriden!')


class BulkNotificationMethod(NotificationMethod):
    def send_bulk(self):
        raise NotImplementedError('The `send` method must be overriden!')
# endregion


# region implementations
class EmailNotification(BulkNotificationMethod):
    METHOD_NAME = 'mail'
    CONTEXT_EXTRA = [
        ('template', ),
        ('template', 'html', ),
        ('template', 'subject', ),
    ]

    def get_recipients(self):
        return EmailAddress.objects.filter(
            user__in=self.targets,
        )

    def send_bulk(self):
        html_message = render_to_string(self.context['template']['html'], self.context)
        recipients = self.recipients.values_list('email', flat=True)

        InvenTree.tasks.send_email(self.context['template']['subject'], '', recipients, html_message=html_message)

        return True

class UIMessageNotification(SingleNotificationMethod):
    METHOD_NAME = 'ui_message'

    def get_recipients(self):
        return self.targets

    def send(self, receiver):
        NotificationMessage.objects.create(
            target_object = self.obj,
            source_object = receiver,
            user = receiver,
            category = self.entry_name,
            name = self.context['name'],
            message = self.context['message'],
        )
# endregion
# endregion<commit_msg>and a bit more renaming<commit_after>import logging
from datetime import timedelta

from django.conf import settings
from django.template.loader import render_to_string

from allauth.account.models import EmailAddress

from InvenTree.helpers import inheritors
from common.models import NotificationEntry, NotificationMessage
import InvenTree.tasks


logger = logging.getLogger('inventree')


# region notification classes
# region base classes
class NotificationMethod:
    METHOD_NAME = ''
    CONTEXT_BUILTIN = ['name', 'message', ]
    CONTEXT_EXTRA = []

    def __init__(self, obj, entry_name, targets, context) -> None:
        # Check if a sending fnc is defined
        if (not hasattr(self, 'send')) and (not hasattr(self, 'send_bulk')):
            raise NotImplementedError('A NotificationMethod must either define a `send` or a `send_bulk` method')

        # No method name is no good
        if self.METHOD_NAME in ('', None):
            raise NotImplementedError(f'The NotificationMethod {self.__class__} did not provide a METHOD_NAME')

        # Define arguments
        self.obj = obj
        self.entry_name = entry_name
        self.targets = targets
        self.context = self.check_context(context)

        # Gather recipients
        self.recipients = self.get_recipients()

    def check_context(self, context):
        def check(ref, obj):
            # the obj is not accesible so we are on the end
            if not isinstance(obj, (list, dict, tuple, )):
                return ref

            # check if the ref exsists
            if isinstance(ref, str):
                if not obj.get(ref):
                    return ref
                return False

            # nested
            elif isinstance(ref, (tuple, list)):
                if len(ref) == 1:
                    return check(ref[0], obj)
                ret = check(ref[0], obj)
                if ret:
                    return ret
                return check(ref[1:], obj[ref[0]])

            # other cases -> raise
            raise NotImplementedError('This type can not be used as a context reference')

        missing = []
        for item in (*self.CONTEXT_BUILTIN, *self.CONTEXT_EXTRA):
            ret = check(item, context)
            if ret:
                missing.append(ret)

        if missing:
            raise NotImplementedError(f'The `context` is missing the following items:\n{missing}')

        return context

    def get_recipients(self):
        raise NotImplementedError('The `get_recipients` method must be implemented!')

    def setup(self):
        return True

    # def send(self, targets)
    # def send_bulk(self)

    def cleanup(self):
        return True


class SingleNotificationMethod(NotificationMethod):
    def send(self, target):
        raise NotImplementedError('The `send` method must be overriden!')


class BulkNotificationMethod(NotificationMethod):
    def send_bulk(self):
        raise NotImplementedError('The `send` method must be overriden!')
# endregion


# region implementations
class EmailNotification(BulkNotificationMethod):
    METHOD_NAME = 'mail'
    CONTEXT_EXTRA = [
        ('template', ),
        ('template', 'html', ),
        ('template', 'subject', ),
    ]

    def get_recipients(self):
        return EmailAddress.objects.filter(
            user__in=self.targets,
        )

    def send_bulk(self):
        html_message = render_to_string(self.context['template']['html'], self.context)
        recipients = self.recipients.values_list('email', flat=True)

        InvenTree.tasks.send_email(self.context['template']['subject'], '', recipients, html_message=html_message)

        return True

class UIMessageNotification(SingleNotificationMethod):
    METHOD_NAME = 'ui_message'

    def get_recipients(self):
        return self.targets

    def send(self, target):
        NotificationMessage.objects.create(
            target_object = self.obj,
            source_object = target,
            user = target,
            category = self.entry_name,
            name = self.context['name'],
            message = self.context['message'],
        )
# endregion
# endregion
{'fraction_non_alphanumeric': 0.09258145966093544, 'fraction_numerical': 0.0012023566189731875, 'mean_word_length': 2.413212966762413, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '5607897', 'n_tokens_mistral': 2300, 'n_tokens_neox': 2177, 'n_words': 627}