<commit_before>import logging

from django.conf import settings
from django.db import models, transaction
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from issues.models import ProposalStatus, IssueStatus, VoteResult
from meetings.models import MeetingParticipant, Meeting
from ocd.base_models import HTMLField, UIDMixin
from ocd.email import send_mails
from ocd.views import get_guests_emails
from users.default_roles import DefaultGroups
from users.models import OCUser, Membership
import issues.models as issues_models
import meetings.models as meetings_models


logger = logging.getLogger(__name__)


class SendToOption(object):
    ONLY_ME = 1
    ONLY_ATTENDEES = 2
    BOARD_ONLY = 3
    ALL_MEMBERS = 4

    choices = (
        (ONLY_ME, _("Me only (review)")),
        (ONLY_ATTENDEES, _("Only attendees")),
        (BOARD_ONLY, _("The board")),
        (ALL_MEMBERS, _("All members")),
    )

    publish_choices = (
        (ONLY_ME, _("Me only (review)")),
        (BOARD_ONLY, _("The board")),
        (ALL_MEMBERS, _("All members")),
    )


class Community(UIDMixin):
    name = models.CharField(max_length=200, verbose_name=_("Name"))
    is_public = models.BooleanField(_("Public community"), default=False,
                                    db_index=True)
    logo = models.ImageField(_("Community logo"), upload_to='community_logo',
                             blank=True, null=True)
    official_identifier = models.CharField(_("Community identifier"),
                                           max_length=300, blank=True,
                                           null=True)

    upcoming_meeting_started = models.BooleanField(_("Meeting started"),
                                                   default=False)
    upcoming_meeting_title = models.CharField(_("Upcoming meeting title"),
                                              max_length=300, null=True,
                                              blank=True)
    upcoming_meeting_scheduled_at = models.DateTimeField(
        _("Upcoming meeting scheduled at"), blank=True, null=True)
    upcoming_meeting_location = models.CharField(
        _("Upcoming meeting location"), max_length=300, null=True, blank=True)
    upcoming_meeting_comments = HTMLField(_("Upcoming meeting background"),
                                          null=True, blank=True)

    upcoming_meeting_participants = models.ManyToManyField(
        settings.AUTH_USER_MODEL, blank=True, related_name="+",
        verbose_name=_("Participants in upcoming meeting"))

    upcoming_meeting_guests = models.TextField(
        _("Guests in upcoming meeting"), null=True, blank=True,
        help_text=_("Enter each guest in a separate line"))

    upcoming_meeting_version = models.IntegerField(
        _("Upcoming meeting version"), default=0)

    upcoming_meeting_is_published = models.BooleanField(
        _("Upcoming meeting is published"), default=False)

    upcoming_meeting_published_at = models.DateTimeField(
        _("Upcoming meeting published at"), blank=True, null=True)

    upcoming_meeting_summary = HTMLField(_("Upcoming meeting summary"),
                                         null=True, blank=True)

    board_name = models.CharField(_("Board name"), default=_("Board"),
                                  max_length=200)

    straw_voting_enabled = models.BooleanField(_("Straw voting enabled"),
                                               default=False)

    issue_ranking_enabled = models.BooleanField(
        _("Issue ranking votes enabled"), default=False)

    voting_ends_at = models.DateTimeField(_("Straw Vote ends at"), null=True,
                                          blank=True)

    referendum_started = models.BooleanField(_("Referendum started"),
                                             default=False)

    referendum_started_at = models.DateTimeField(_("Referendum started at"),
                                                 null=True, blank=True)

    referendum_ends_at = models.DateTimeField(_("Referendum ends at"),
                                              null=True, blank=True)

    default_quorum = models.PositiveSmallIntegerField(_("Default quorum"),
                                                      null=True, blank=True)

    allow_links_in_emails = models.BooleanField(
        _("Allow links inside emails"), default=True)

    email_invitees = models.BooleanField(_("Send mails to invitees"),
                                         default=False)

    register_missing_board_members = models.BooleanField(
        _("Resister missing board members"), default=False)

    class Meta:
        verbose_name = _("Community")
        verbose_name_plural = _("Communities")

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return "community", (str(self.pk),)

    @models.permalink
    def get_upcoming_absolute_url(self):
        return "community", (str(self.pk),)

    def upcoming_issues(self, upcoming=True):
        l = issues_models.IssueStatus.IS_UPCOMING if upcoming else \
            issues_models.IssueStatus.NOT_IS_UPCOMING
        return self.issues.filter(active=True, status__in=(l)
        ).order_by('order_in_upcoming_meeting')

    def available_issues(self):
        return self.issues.filter(active=True,
                                  status=issues_models.IssueStatus.OPEN
        ).order_by('-created_at')

    def available_issues_by_rank(self):
        return self.issues.filter(active=True,
                                  status=issues_models.IssueStatus.OPEN
        ).order_by('order_by_votes')

    def issues_ready_to_close(self):
        return self.upcoming_issues().filter(
            proposals__active=True,
            proposals__decided_at_meeting=None,
            proposals__status__in=[
                ProposalStatus.ACCEPTED,
                ProposalStatus.REJECTED
            ]
        )

    def get_board_name(self):
        return self.board_name or _('Board')

    def get_members(self):
        return OCUser.objects.filter(memberships__community=self)

    def meeting_participants(self):

        meeting_participants = {'board': [], 'members': [], }

        board_ids = [m.user.id for m in self.memberships.board()]

        for u in self.upcoming_meeting_participants.all():
            if u.id in board_ids:
                meeting_participants['board'].append(u)
            else:
                meeting_participants['members'].append(u)

        return meeting_participants

    def previous_members_participations(self):
        participations = MeetingParticipant.objects.filter( \
            default_group_name=DefaultGroups.MEMBER,
            meeting__community=self) \
            .order_by('-meeting__held_at')

        return list(set([p.user for p in participations]) - \
                    set(self.upcoming_meeting_participants.all()))

        """                             
                                    memberships__default_group_name=DefaultGroups.MEMBER).annotate\
                                    (meeting_participant=Count('participations'), \
                                     last_meeting=Max('participations__meeting__held_at')).exclude(id__in=self.upcoming_meeting_participants.all())\
                                     .order_by('-last_meeting','-meeting_participant')
        """


    def previous_guests_participations(self):
        guests_list = Meeting.objects.filter(community=self) \
            .values_list('guests', flat=True)

        prev_guests = set()
        upcoming_guests = self.upcoming_meeting_guests or ' '
        for guest in guests_list:
            if guest:
                prev_guests.update(guest.splitlines())
        prev_guests.difference_update(upcoming_guests.splitlines())
        return prev_guests


    def get_board_members(self):
        board_memberships = Membership.objects.filter(community=self) \
            .exclude(default_group_name=DefaultGroups.MEMBER)
        return [m.user for m in board_memberships]

    def get_none_board_members(self):
        return Membership.objects.filter(community=self,
                                         default_group_name=DefaultGroups.MEMBER)

    def get_guest_list(self):
        if not self.upcoming_meeting_guests:<commit_msg>Cleanup<commit_after>import logging

from django.conf import settings
from django.db import models, transaction
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from issues.models import ProposalStatus, IssueStatus, VoteResult
from meetings.models import MeetingParticipant, Meeting
from ocd.base_models import HTMLField, UIDMixin
from ocd.email import send_mails
from ocd.views import get_guests_emails
from users.default_roles import DefaultGroups
from users.models import OCUser, Membership
import issues.models as issues_models
import meetings.models as meetings_models


logger = logging.getLogger(__name__)


class SendToOption(object):
    ONLY_ME = 1
    ONLY_ATTENDEES = 2
    BOARD_ONLY = 3
    ALL_MEMBERS = 4

    choices = (
        (ONLY_ME, _("Me only (review)")),
        (ONLY_ATTENDEES, _("Only attendees")),
        (BOARD_ONLY, _("The board")),
        (ALL_MEMBERS, _("All members")),
    )

    publish_choices = (
        (ONLY_ME, _("Me only (review)")),
        (BOARD_ONLY, _("The board")),
        (ALL_MEMBERS, _("All members")),
    )


class Community(UIDMixin):
    name = models.CharField(max_length=200, verbose_name=_("Name"))
    is_public = models.BooleanField(_("Public community"), default=False,
                                    db_index=True)
    logo = models.ImageField(_("Community logo"), upload_to='community_logo',
                             blank=True, null=True)
    official_identifier = models.CharField(_("Community identifier"),
                                           max_length=300, blank=True,
                                           null=True)

    upcoming_meeting_started = models.BooleanField(_("Meeting started"),
                                                   default=False)
    upcoming_meeting_title = models.CharField(_("Upcoming meeting title"),
                                              max_length=300, null=True,
                                              blank=True)
    upcoming_meeting_scheduled_at = models.DateTimeField(
        _("Upcoming meeting scheduled at"), blank=True, null=True)
    upcoming_meeting_location = models.CharField(
        _("Upcoming meeting location"), max_length=300, null=True, blank=True)
    upcoming_meeting_comments = HTMLField(_("Upcoming meeting background"),
                                          null=True, blank=True)

    upcoming_meeting_participants = models.ManyToManyField(
        settings.AUTH_USER_MODEL, blank=True, related_name="+",
        verbose_name=_("Participants in upcoming meeting"))

    upcoming_meeting_guests = models.TextField(
        _("Guests in upcoming meeting"), null=True, blank=True,
        help_text=_("Enter each guest in a separate line"))

    upcoming_meeting_version = models.IntegerField(
        _("Upcoming meeting version"), default=0)

    upcoming_meeting_is_published = models.BooleanField(
        _("Upcoming meeting is published"), default=False)

    upcoming_meeting_published_at = models.DateTimeField(
        _("Upcoming meeting published at"), blank=True, null=True)

    upcoming_meeting_summary = HTMLField(_("Upcoming meeting summary"),
                                         null=True, blank=True)

    board_name = models.CharField(_("Board name"), default=_("Board"),
                                  max_length=200)

    straw_voting_enabled = models.BooleanField(_("Straw voting enabled"),
                                               default=False)

    issue_ranking_enabled = models.BooleanField(
        _("Issue ranking votes enabled"), default=False)

    voting_ends_at = models.DateTimeField(_("Straw Vote ends at"), null=True,
                                          blank=True)

    referendum_started = models.BooleanField(_("Referendum started"),
                                             default=False)

    referendum_started_at = models.DateTimeField(_("Referendum started at"),
                                                 null=True, blank=True)

    referendum_ends_at = models.DateTimeField(_("Referendum ends at"),
                                              null=True, blank=True)

    default_quorum = models.PositiveSmallIntegerField(_("Default quorum"),
                                                      null=True, blank=True)

    allow_links_in_emails = models.BooleanField(
        _("Allow links inside emails"), default=True)

    email_invitees = models.BooleanField(_("Send mails to invitees"),
                                         default=False)

    register_missing_board_members = models.BooleanField(
        _("Resister missing board members"), default=False)

    class Meta:
        verbose_name = _("Community")
        verbose_name_plural = _("Communities")

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return "community", (str(self.pk),)

    @models.permalink
    def get_upcoming_absolute_url(self):
        return "community", (str(self.pk),)

    def upcoming_issues(self, upcoming=True):
        l = issues_models.IssueStatus.IS_UPCOMING if upcoming else \
            issues_models.IssueStatus.NOT_IS_UPCOMING
        return self.issues.filter(active=True, status__in=(l)
        ).order_by('order_in_upcoming_meeting')

    def available_issues(self):
        return self.issues.filter(active=True,
                                  status=issues_models.IssueStatus.OPEN
        ).order_by('-created_at')

    def available_issues_by_rank(self):
        return self.issues.filter(active=True,
                                  status=issues_models.IssueStatus.OPEN
        ).order_by('order_by_votes')

    def issues_ready_to_close(self):
        return self.upcoming_issues().filter(
            proposals__active=True,
            proposals__decided_at_meeting=None,
            proposals__status__in=[
                ProposalStatus.ACCEPTED,
                ProposalStatus.REJECTED
            ]
        )

    def get_board_name(self):
        return self.board_name or _('Board')

    def get_members(self):
        return OCUser.objects.filter(memberships__community=self)

    def meeting_participants(self):

        meeting_participants = {'board': [], 'members': [], }

        board_ids = [m.user.id for m in self.memberships.board()]

        for u in self.upcoming_meeting_participants.all():
            if u.id in board_ids:
                meeting_participants['board'].append(u)
            else:
                meeting_participants['members'].append(u)

        return meeting_participants

    def previous_members_participations(self):
        participations = MeetingParticipant.objects.filter( \
            default_group_name=DefaultGroups.MEMBER,
            meeting__community=self) \
            .order_by('-meeting__held_at')

        return list(set([p.user for p in participations]) - \
                    set(self.upcoming_meeting_participants.all()))


    def previous_guests_participations(self):
        guests_list = Meeting.objects.filter(community=self) \
            .values_list('guests', flat=True)

        prev_guests = set()
        upcoming_guests = self.upcoming_meeting_guests or ' '
        for guest in guests_list:
            if guest:
                prev_guests.update(guest.splitlines())
        prev_guests.difference_update(upcoming_guests.splitlines())
        return prev_guests


    def get_board_members(self):
        board_memberships = Membership.objects.filter(community=self) \
            .exclude(default_group_name=DefaultGroups.MEMBER)
        return [m.user for m in board_memberships]

    def get_none_board_members(self):
        return Membership.objects.filter(community=self,
                                         default_group_name=DefaultGroups.MEMBER)

    def get_guest_list(self):
        if not self.upcoming_meeting_guests:
{'fraction_non_alphanumeric': 0.09015392132909845, 'fraction_numerical': 0.002443195699975568, 'mean_word_length': 2.320421821131616, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 73, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6479830', 'n_tokens_mistral': 4477, 'n_tokens_neox': 4272, 'n_words': 841}