aboutsummaryrefslogtreecommitdiff
blob: a55f38cfcf40aacaf82f1bcb9102afc342ff019e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"""
djeuscan.managers
"""

from django.db import models
from djeuscan.helpers import xint, rename_fields, select_related_last_versions


def _gen_n_function(field_name):
    def n_method(self):
        res = self.aggregate(models.Sum(field_name))[field_name + '__sum']
        return xint(res)
    n_method.func_name = field_name
    return n_method


def _gen_for_function(field):
    def for_method(self, val, last_versions=False):
        """
        Returns packages that belong to the given parametrs
        """
        res = self.filter(**{field: val})

        if last_versions:
            select_related_last_versions(res)

        return res

    for_method.func_name = 'for_' + field
    return for_method


ANNOTATE_DICT = {name: models.Sum(name)
                 for name in ['n_packaged', 'n_overlay', 'n_versions']}


class PackageMixin(object):
    for_maintainer = _gen_for_function('maintainers')
    for_herd = _gen_for_function('herds')
    for_category = _gen_for_function('category')

    n_packaged = _gen_n_function("n_packaged")
    n_overlay = _gen_n_function("n_overlay")
    n_versions = _gen_n_function("n_versions")

    def n_upstream(self):
        return self.n_versions() - self.n_packaged() - self.n_overlay()

    def categories(self):
        """
        Returns all the available categories
        """
        return self.values('category').annotate(**ANNOTATE_DICT)

    def herds(self, ids=None, rename=False):
        """
        Returns all the available herds
        """
        # FIXME: optimize the query, it uses 'LEFT OUTER JOIN' instead of
        # 'INNER JOIN'
        if ids is not None:
            res = self.filter(herds__id__in=ids)
        else:
            res = self.filter(herds__isnull=False)
        res = res.values('herds__herd').annotate(**ANNOTATE_DICT)

        if rename:
            res = rename_fields(res, [('herds__herd', 'herd')])

        return res

    def maintainers(self, ids=None, rename=False):
        """
        Returns all the available maintainers
        """
        if ids is not None:
            res = self.filter(maintainers__id__in=ids)
        else:
            res = self.filter(maintainers__isnull=False)

        res = res.values(
            'maintainers__id', 'maintainers__name', 'maintainers__email'
        )
        res = res.annotate(**ANNOTATE_DICT)

        if rename:
            res = rename_fields(
                res,
                [('maintainers__id', 'id'),
                ('maintainers__name', 'name'),
                ('maintainers__email', 'email')]
            )

        return res

    def overlays(self):
        """
        Returns the all available overlays
        """
        res = self.values('version__overlay').exclude(version__overlay='')
        return [o["version__overlay"] for o in res.distinct()]

    def for_overlay(self, overlay):
        """
        Returns packages that belong to the given overlay
        """
        packages = self.values(
            'id', 'name', 'category', 'n_versions', 'n_packaged', 'n_overlay'
        )
        return packages.filter(version__overlay=overlay).distinct()

    def for_handler(self, handler):
        """
        Returns packages that belong to the given handler
        """
        packages = self.values(
            'id', 'name', 'category', 'n_versions', 'n_packaged', 'n_overlay'
        )
        return packages.filter(version__handler=handler,
                               version__overlay="").distinct()


class PackageQuerySet(models.query.QuerySet, PackageMixin):
    pass


class PackageManager(models.Manager, PackageMixin):
    def get_query_set(self):
        return PackageQuerySet(self.model, using=self._db)


class VersionLogMixin(object):
    def for_package(self, package, order=False):
        res = self.filter(package=package)
        if order:
            res = res.order_by('-id')
        return res

    def for_maintainer(self, maintainer, order=False):
        res = self.filter(package__maintainers__id=maintainer.id)
        if order:
            res = res.order_by('-id')
        return res

    def for_category(self, category, order=False):
        res = self.filter(package__category=category)
        if order:
            res = res.order_by('-id')
        return res

    def for_herd(self, herd, order=False):
        res = self.filter(package__herds__id=herd.id)
        if order:
            res = res.order_by('-id')
        return res


class VersionLogQuerySet(models.query.QuerySet, VersionLogMixin):
    pass


class VersionLogManager(models.Manager, VersionLogMixin):
    def get_query_set(self):
        return VersionLogQuerySet(self.model, using=self._db)


class EuscanResultMixin(object):
    def for_package(self, package):
        return self.filter(package=package)

    def for_maintainer(self, maintainer):
        return self.filter(package__maintainers__id=maintainer.id)

    def for_category(self, category):
        return self.filter(package__category=category)

    def for_herd(self, herd):
        return self.filter(package__herds__id=herd.id)


class EuscanResultQuerySet(models.query.QuerySet, EuscanResultMixin):
    pass


class EuscanResultManager(models.Manager, EuscanResultMixin):
    def get_query_set(self):
        return EuscanResultQuerySet(self.model, using=self._db)