<commit_before># -*- coding: UTF-8 -*-
# Copyright 2016-2018 Rumma & Ko Ltd
# License: BSD (see file COPYING for details)

"""Database models specific for the Team variant of Lino Noi.

Defines a customized :class:`TicketDetail`.

"""
from __future__ import print_function

from lino_xl.lib.tickets.models import *
from lino.modlib.users.mixins import Assignable
from lino.api import _

from lino_xl.lib.working.choicelists import ReportingTypes, ZERO_DURATION
from lino.modlib.summaries.mixins import Summarized


def get_summary_fields():
    for t in ReportingTypes.get_list_items():
        yield t.name + '_hours'

class Site(Site):

    class Meta(Site.Meta):
        app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Site')

    def get_change_observers(self, ar=None):
        action = ar.bound_action.action if ar.bound_action else None
        if ar is not None and isinstance(action, CreateRow) and issubclass(ar.actor.model,Ticket):
            subs = rt.models.tickets.Subscription.objects.filter(site=ar.selected_rows[-1].site)
            for (u, um) in [(u, u.mail_mode) for u in [sub.user for sub in subs]
                            if (u.user_type and u.user_type.has_required_roles([Triager])
                                and u != ar.get_user())]:
                yield (u, um)
        else:
            for s in rt.models.tickets.Subscription.objects.filter(site=self):
                yield (s.user, s.user.mail_mode)

    def after_ui_create(self, ar):
        super(Site, self).after_ui_create(ar)
        rt.models.tickets.Subscription.objects.create(user=ar.get_user(), site=self)


class Ticket(Ticket, Assignable, Summarized):

    class Meta(Ticket.Meta):
        # app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Ticket')

    def assigned_to_changed(self, ar):
        """Add a star and send notification of Assignment"""
        # self.add_change_watcher(self.assigned_to)

        if (self.assigned_to is not None and
                self.assigned_to != ar.user and
                dd.is_installed('notify')):
            ctx = dict(user=ar.user, what=ar.obj2memo(self))
            def msg(user, mm):
                subject = _("{user} has assigned you to ticket: {what}").format(**ctx)
                return (subject , tostring(E.span(subject)))

            mt = rt.models.notify.MessageTypes.tickets

            rt.models.notify.Message.emit_notification(
                ar, self, mt, msg,
                [(self.assigned_to, self.assigned_to.mail_mode)]
            )
    # def end_user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.end_user)

    # def user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.user)

    def after_ui_create(self, ar):
        # print("Create")
        # self.site_changed(ar)
        # self.assigned_to_changed(ar)
        # self.end_user_changed(ar)
        # self.user_changed(ar)
        super(Ticket, self).after_ui_create(ar)

    show_commits = dd.ShowSlaveTable('github.CommitsByTicket')
    show_changes = dd.ShowSlaveTable('changes.ChangesByMaster')
    # show_wishes = dd.ShowSlaveTable('deploy.DeploymentsByTicket')
    # show_stars = dd.ShowSlaveTable('stars.AllStarsByController')


    def get_change_subject(self, ar, cw):
        ctx = dict(user=ar.user, what=str(self))
        if cw is None:
            return _("{user} submitted ticket {what}").format(**ctx)
        if len(list(cw.get_updates())) == 0:
            return
        return _("{user} modified {what}").format(**ctx)

    def get_change_body(self, ar, cw):
        ctx = dict(user=ar.user, what=ar.obj2memo(self))
        if cw is None:
            elems = [E.p(
                _("{user} submitted ticket {what}").format(**ctx), ".")]
            elems += list(self.get_change_info(ar, cw))
        else:
            items = list(cw.get_updates_html(["_user_cache"]))
            if len(items) == 0:
                return
            elems = []
            elems += list(self.get_change_info(ar, cw))
            elems.append(E.p(
                _("{user} modified {what}").format(**ctx), ":"))
            elems.append(E.ul(*items))
        # print("20170210 {}".format(tostring(E.div(*elems))))
        return tostring(E.div(*elems))

    @classmethod
    def get_layout_aliases(cls):
        yield ("SUMMARY_FIELDS", ' '.join(get_summary_fields()))

    # @classmethod
    # def get_summary_master_model(cls):
    #     return cls

    def reset_summary_data(self):
        for k in get_summary_fields():
            setattr(self, k, ZERO_DURATION)
        self.last_commenter = None

    def get_summary_collectors(self):
        qs = rt.models.working.Session.objects.filter(ticket=self)
        yield (self.add_from_session, qs)
        qs = rt.models.comments.Comment.objects.filter(**gfk2lookup(rt.models.comments.Comment._meta.get_field("owner"),
                                                                    self)
                                                       ).order_by("-created")[0:1]
        yield (self.add_from_comment, qs)

    def add_from_comment(self, obj):
        self.last_commenter = obj.user

    def add_from_session(self, obj):
        d = obj.get_duration()
        if d:
            rt = obj.get_reporting_type()
            k = rt.name + '_hours'
            value = getattr(self, k) + d
            setattr(self, k, value)\

    @dd.chooser()
    def site_choices(cls, end_user, user, ar):
        user = user if user is not None else ar.get_user()
        sub_user = [user.pk]
        if end_user: sub_user.append(end_user.pk)
        pks = rt.models.tickets.Subscription.objects.filter(user__pk__in=sub_user).values_list("site__pk", flat=True)
        print(pks)
        return Site.objects.filter(id__in=pks)


class TicketDetail(TicketDetail):
    """Customized detail_layout for Tickets in Noi

    """
    main = "general more comments.CommentsByMentioned #history_tab #more2 #github.CommitsByTicket"

    general = dd.Panel("""
    general1:60 comments.CommentsByRFC:30
    """, label=_("General"))

    general1 = """
    general1a:30 general1b:30
    """<commit_msg>Ticket.site_choices() was obsolete and untested<commit_after># -*- coding: UTF-8 -*-
# Copyright 2016-2018 Rumma & Ko Ltd
# License: BSD (see file COPYING for details)

"""Database models specific for the Team variant of Lino Noi.

Defines a customized :class:`TicketDetail`.

"""
from __future__ import print_function

from lino_xl.lib.tickets.models import *
from lino.modlib.users.mixins import Assignable
from lino.api import _

from lino_xl.lib.working.choicelists import ReportingTypes, ZERO_DURATION
from lino.modlib.summaries.mixins import Summarized


def get_summary_fields():
    for t in ReportingTypes.get_list_items():
        yield t.name + '_hours'

class Site(Site):

    class Meta(Site.Meta):
        app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Site')

    def get_change_observers(self, ar=None):
        action = ar.bound_action.action if ar.bound_action else None
        if ar is not None and isinstance(action, CreateRow) and issubclass(ar.actor.model,Ticket):
            subs = rt.models.tickets.Subscription.objects.filter(site=ar.selected_rows[-1].site)
            for (u, um) in [(u, u.mail_mode) for u in [sub.user for sub in subs]
                            if (u.user_type and u.user_type.has_required_roles([Triager])
                                and u != ar.get_user())]:
                yield (u, um)
        else:
            for s in rt.models.tickets.Subscription.objects.filter(site=self):
                yield (s.user, s.user.mail_mode)

    def after_ui_create(self, ar):
        super(Site, self).after_ui_create(ar)
        rt.models.tickets.Subscription.objects.create(user=ar.get_user(), site=self)


class Ticket(Ticket, Assignable, Summarized):

    class Meta(Ticket.Meta):
        # app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Ticket')

    def assigned_to_changed(self, ar):
        """Add a star and send notification of Assignment"""
        # self.add_change_watcher(self.assigned_to)

        if (self.assigned_to is not None and
                self.assigned_to != ar.user and
                dd.is_installed('notify')):
            ctx = dict(user=ar.user, what=ar.obj2memo(self))
            def msg(user, mm):
                subject = _("{user} has assigned you to ticket: {what}").format(**ctx)
                return (subject , tostring(E.span(subject)))

            mt = rt.models.notify.MessageTypes.tickets

            rt.models.notify.Message.emit_notification(
                ar, self, mt, msg,
                [(self.assigned_to, self.assigned_to.mail_mode)]
            )
    # def end_user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.end_user)

    # def user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.user)

    def after_ui_create(self, ar):
        # print("Create")
        # self.site_changed(ar)
        # self.assigned_to_changed(ar)
        # self.end_user_changed(ar)
        # self.user_changed(ar)
        super(Ticket, self).after_ui_create(ar)

    show_commits = dd.ShowSlaveTable('github.CommitsByTicket')
    show_changes = dd.ShowSlaveTable('changes.ChangesByMaster')
    # show_wishes = dd.ShowSlaveTable('deploy.DeploymentsByTicket')
    # show_stars = dd.ShowSlaveTable('stars.AllStarsByController')


    def get_change_subject(self, ar, cw):
        ctx = dict(user=ar.user, what=str(self))
        if cw is None:
            return _("{user} submitted ticket {what}").format(**ctx)
        if len(list(cw.get_updates())) == 0:
            return
        return _("{user} modified {what}").format(**ctx)

    def get_change_body(self, ar, cw):
        ctx = dict(user=ar.user, what=ar.obj2memo(self))
        if cw is None:
            elems = [E.p(
                _("{user} submitted ticket {what}").format(**ctx), ".")]
            elems += list(self.get_change_info(ar, cw))
        else:
            items = list(cw.get_updates_html(["_user_cache"]))
            if len(items) == 0:
                return
            elems = []
            elems += list(self.get_change_info(ar, cw))
            elems.append(E.p(
                _("{user} modified {what}").format(**ctx), ":"))
            elems.append(E.ul(*items))
        # print("20170210 {}".format(tostring(E.div(*elems))))
        return tostring(E.div(*elems))

    @classmethod
    def get_layout_aliases(cls):
        yield ("SUMMARY_FIELDS", ' '.join(get_summary_fields()))

    # @classmethod
    # def get_summary_master_model(cls):
    #     return cls

    def reset_summary_data(self):
        for k in get_summary_fields():
            setattr(self, k, ZERO_DURATION)
        self.last_commenter = None

    def get_summary_collectors(self):
        qs = rt.models.working.Session.objects.filter(ticket=self)
        yield (self.add_from_session, qs)
        qs = rt.models.comments.Comment.objects.filter(**gfk2lookup(rt.models.comments.Comment._meta.get_field("owner"),
                                                                    self)
                                                       ).order_by("-created")[0:1]
        yield (self.add_from_comment, qs)

    def add_from_comment(self, obj):
        self.last_commenter = obj.user

    def add_from_session(self, obj):
        d = obj.get_duration()
        if d:
            rt = obj.get_reporting_type()
            k = rt.name + '_hours'
            value = getattr(self, k) + d
            setattr(self, k, value)\

    @dd.chooser()
    def site_choices(cls, ar):
        # if user is None:
        #     user = ar.get_user()
        user = ar.get_user()
        # user = user if user is not None else ar.get_user()
        group_ids = rt.models.groups.Membership.objects.filter(user=user).values_list("group__pk", flat=True)
        # user_ids = [user.pk]
        # if end_user: user_ids.append(end_user.pk)
        # pks = rt.models.tickets.Subscription.objects.filter(user__pk__in=user_ids).values_list("site__pk", flat=True)
        # # print(pks)
        # return Site.objects.filter(id__in=pks)
        return Site.objects.filter(group__in=group_ids)


class TicketDetail(TicketDetail):
    """Customized detail_layout for Tickets in Noi

    """
    main = "general more comments.CommentsByMentioned #history_tab #more2 #github.CommitsByTicket"

    general = dd.Panel("""
    general1:60 comments.CommentsByRFC:30
    """, label=_("General"))

    general1 = """
    general1a:30 general1b:30
    """
{'fraction_non_alphanumeric': 0.12390773832952846, 'fraction_numerical': 0.005982838699519799, 'mean_word_length': 2.388636969858629, 'pattern_counts': {'":': 2, '<': 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': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '100067', 'n_tokens_mistral': 4179, 'n_tokens_neox': 4005, 'n_words': 803}