diff options
10 files changed, 27 insertions, 702 deletions
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/.gitignore b/bitbake/lib/toaster/contrib/django-aggregate-if-master/.gitignore deleted file mode 100644 index c45652d29b..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/.gitignore +++ /dev/null | |||
| @@ -1,10 +0,0 @@ | |||
| 1 | *.pyc | ||
| 2 | *.swp | ||
| 3 | *.swo | ||
| 4 | *.kpf | ||
| 5 | *.egg-info/ | ||
| 6 | .idea | ||
| 7 | .tox | ||
| 8 | tmp/ | ||
| 9 | dist/ | ||
| 10 | .DS_Store | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/.travis.yml b/bitbake/lib/toaster/contrib/django-aggregate-if-master/.travis.yml deleted file mode 100644 index a920f3945c..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/.travis.yml +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | language: python | ||
| 2 | python: | ||
| 3 | - "2.7" | ||
| 4 | - "3.4" | ||
| 5 | services: | ||
| 6 | - mysql | ||
| 7 | - postgresql | ||
| 8 | env: | ||
| 9 | - DJANGO=1.4 DB=sqlite | ||
| 10 | - DJANGO=1.4 DB=mysql | ||
| 11 | - DJANGO=1.4 DB=postgres | ||
| 12 | - DJANGO=1.5 DB=sqlite | ||
| 13 | - DJANGO=1.5 DB=mysql | ||
| 14 | - DJANGO=1.5 DB=postgres | ||
| 15 | - DJANGO=1.6 DB=sqlite | ||
| 16 | - DJANGO=1.6 DB=mysql | ||
| 17 | - DJANGO=1.6 DB=postgres | ||
| 18 | - DJANGO=1.7 DB=sqlite | ||
| 19 | - DJANGO=1.7 DB=mysql | ||
| 20 | - DJANGO=1.7 DB=postgres | ||
| 21 | |||
| 22 | matrix: | ||
| 23 | exclude: | ||
| 24 | - python: "3.4" | ||
| 25 | env: DJANGO=1.4 DB=sqlite | ||
| 26 | - python: "3.4" | ||
| 27 | env: DJANGO=1.4 DB=mysql | ||
| 28 | - python: "3.4" | ||
| 29 | env: DJANGO=1.4 DB=postgres | ||
| 30 | - python: "3.4" | ||
| 31 | env: DJANGO=1.5 DB=sqlite | ||
| 32 | - python: "3.4" | ||
| 33 | env: DJANGO=1.5 DB=mysql | ||
| 34 | - python: "3.4" | ||
| 35 | env: DJANGO=1.5 DB=postgres | ||
| 36 | - python: "3.4" | ||
| 37 | env: DJANGO=1.6 DB=mysql | ||
| 38 | - python: "3.4" | ||
| 39 | env: DJANGO=1.7 DB=mysql | ||
| 40 | |||
| 41 | before_script: | ||
| 42 | - mysql -e 'create database aggregation;' | ||
| 43 | - psql -c 'create database aggregation;' -U postgres | ||
| 44 | install: | ||
| 45 | - pip install six | ||
| 46 | - if [ "$DB" == "mysql" ]; then pip install mysql-python; fi | ||
| 47 | - if [ "$DB" == "postgres" ]; then pip install psycopg2; fi | ||
| 48 | - pip install -q Django==$DJANGO --use-mirrors | ||
| 49 | script: | ||
| 50 | - ./runtests.py --settings=tests.test_$DB | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/LICENSE b/bitbake/lib/toaster/contrib/django-aggregate-if-master/LICENSE deleted file mode 100644 index 6b7c3b174e..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/LICENSE +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | The MIT License | ||
| 2 | |||
| 3 | Copyright (c) 2012 Henrique Bastos | ||
| 4 | |||
| 5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | of this software and associated documentation files (the "Software"), to deal | ||
| 7 | in the Software without restriction, including without limitation the rights | ||
| 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | copies of the Software, and to permit persons to whom the Software is | ||
| 10 | furnished to do so, subject to the following conditions: | ||
| 11 | |||
| 12 | The above copyright notice and this permission notice shall be included in | ||
| 13 | all copies or substantial portions of the Software. | ||
| 14 | |||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 21 | THE SOFTWARE. | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/README.rst b/bitbake/lib/toaster/contrib/django-aggregate-if-master/README.rst deleted file mode 100644 index 739d4daccf..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/README.rst +++ /dev/null | |||
| @@ -1,156 +0,0 @@ | |||
| 1 | Django Aggregate If: Condition aggregates for Django | ||
| 2 | ==================================================== | ||
| 3 | |||
| 4 | .. image:: https://travis-ci.org/henriquebastos/django-aggregate-if.png?branch=master | ||
| 5 | :target: https://travis-ci.org/henriquebastos/django-aggregate-if | ||
| 6 | :alt: Test Status | ||
| 7 | |||
| 8 | .. image:: https://landscape.io/github/henriquebastos/django-aggregate-if/master/landscape.png | ||
| 9 | :target: https://landscape.io/github/henriquebastos/django-aggregate-if/master | ||
| 10 | :alt: Code Helth | ||
| 11 | |||
| 12 | .. image:: https://pypip.in/v/django-aggregate-if/badge.png | ||
| 13 | :target: https://crate.io/packages/django-aggregate-if/ | ||
| 14 | :alt: Latest PyPI version | ||
| 15 | |||
| 16 | .. image:: https://pypip.in/d/django-aggregate-if/badge.png | ||
| 17 | :target: https://crate.io/packages/django-aggregate-if/ | ||
| 18 | :alt: Number of PyPI downloads | ||
| 19 | |||
| 20 | *Aggregate-if* adds conditional aggregates to Django. | ||
| 21 | |||
| 22 | Conditional aggregates can help you reduce the ammount of queries to obtain | ||
| 23 | aggregated information, like statistics for example. | ||
| 24 | |||
| 25 | Imagine you have a model ``Offer`` like this one: | ||
| 26 | |||
| 27 | .. code-block:: python | ||
| 28 | |||
| 29 | class Offer(models.Model): | ||
| 30 | sponsor = models.ForeignKey(User) | ||
| 31 | price = models.DecimalField(max_digits=9, decimal_places=2) | ||
| 32 | status = models.CharField(max_length=30) | ||
| 33 | expire_at = models.DateField(null=True, blank=True) | ||
| 34 | created_at = models.DateTimeField(auto_now_add=True) | ||
| 35 | updated_at = models.DateTimeField(auto_now=True) | ||
| 36 | |||
| 37 | OPEN = "OPEN" | ||
| 38 | REVOKED = "REVOKED" | ||
| 39 | PAID = "PAID" | ||
| 40 | |||
| 41 | Let's say you want to know: | ||
| 42 | |||
| 43 | #. How many offers exists in total; | ||
| 44 | #. How many of them are OPEN, REVOKED or PAID; | ||
| 45 | #. How much money was offered in total; | ||
| 46 | #. How much money is in OPEN, REVOKED and PAID offers; | ||
| 47 | |||
| 48 | To get these informations, you could query: | ||
| 49 | |||
| 50 | .. code-block:: python | ||
| 51 | |||
| 52 | from django.db.models import Count, Sum | ||
| 53 | |||
| 54 | Offer.objects.count() | ||
| 55 | Offer.objects.filter(status=Offer.OPEN).aggregate(Count('pk')) | ||
| 56 | Offer.objects.filter(status=Offer.REVOKED).aggregate(Count('pk')) | ||
| 57 | Offer.objects.filter(status=Offer.PAID).aggregate(Count('pk')) | ||
| 58 | Offer.objects.aggregate(Sum('price')) | ||
| 59 | Offer.objects.filter(status=Offer.OPEN).aggregate(Sum('price')) | ||
| 60 | Offer.objects.filter(status=Offer.REVOKED).aggregate(Sum('price')) | ||
| 61 | Offer.objects.filter(status=Offer.PAID).aggregate(Sum('price')) | ||
| 62 | |||
| 63 | In this case, **8 queries** were needed to retrieve the desired information. | ||
| 64 | |||
| 65 | With conditional aggregates you can get it all with only **1 query**: | ||
| 66 | |||
| 67 | .. code-block:: python | ||
| 68 | |||
| 69 | from django.db.models import Q | ||
| 70 | from aggregate_if import Count, Sum | ||
| 71 | |||
| 72 | Offer.objects.aggregate( | ||
| 73 | pk__count=Count('pk'), | ||
| 74 | pk__open__count=Count('pk', only=Q(status=Offer.OPEN)), | ||
| 75 | pk__revoked__count=Count('pk', only=Q(status=Offer.REVOKED)), | ||
| 76 | pk__paid__count=Count('pk', only=Q(status=Offer.PAID)), | ||
| 77 | pk__sum=Sum('price'), | ||
| 78 | pk__open__sum=Sum('price', only=Q(status=Offer.OPEN)), | ||
| 79 | pk__revoked__sum=Sum('price'), only=Q(status=Offer.REVOKED)), | ||
| 80 | pk__paid__sum=Sum('price'), only=Q(status=Offer.PAID)) | ||
| 81 | ) | ||
| 82 | |||
| 83 | Installation | ||
| 84 | ------------ | ||
| 85 | |||
| 86 | *Aggregate-if* works with Django 1.4, 1.5, 1.6 and 1.7. | ||
| 87 | |||
| 88 | To install it, simply: | ||
| 89 | |||
| 90 | .. code-block:: bash | ||
| 91 | |||
| 92 | $ pip install django-aggregate-if | ||
| 93 | |||
| 94 | Inspiration | ||
| 95 | ----------- | ||
| 96 | |||
| 97 | There is a 5 years old `ticket 11305`_ that will (*hopefully*) implement this feature into | ||
| 98 | Django 1.8. | ||
| 99 | |||
| 100 | Using Django 1.6, I still wanted to avoid creating custom queries for very simple | ||
| 101 | conditional aggregations. So I've cherry picked those ideas and others from the | ||
| 102 | internet and built this library. | ||
| 103 | |||
| 104 | This library uses the same API and tests proposed on `ticket 11305`_, so when the | ||
| 105 | new feature is available you can easily replace ``django-aggregate-if``. | ||
| 106 | |||
| 107 | Limitations | ||
| 108 | ----------- | ||
| 109 | |||
| 110 | Conditions involving joins with aliases are not supported yet. If you want to | ||
| 111 | help adding this feature, you're welcome to check the `first issue`_. | ||
| 112 | |||
| 113 | Contributors | ||
| 114 | ------------ | ||
| 115 | |||
| 116 | * `Henrique Bastos <http://github.com/henriquebastos>`_ | ||
| 117 | * `Iuri de Silvio <https://github.com/iurisilvio>`_ | ||
| 118 | * `Hampus Stjernhav <https://github.com/champ>`_ | ||
| 119 | * `Bradley Martsberger <https://github.com/martsberger>`_ | ||
| 120 | * `Markus Bertheau <https://github.com/mbertheau>`_ | ||
| 121 | * `end0 <https://github.com/end0>`_ | ||
| 122 | * `Scott Sexton <https://github.com/scottsexton>`_ | ||
| 123 | * `Mauler <https://github.com/mauler>`_ | ||
| 124 | * `trbs <https://github.com/trbs>`_ | ||
| 125 | |||
| 126 | Changelog | ||
| 127 | --------- | ||
| 128 | |||
| 129 | 0.5 | ||
| 130 | - Support for Django 1.7 | ||
| 131 | |||
| 132 | 0.4 | ||
| 133 | - Use tox to run tests. | ||
| 134 | - Add support for Django 1.6. | ||
| 135 | - Add support for Python3. | ||
| 136 | - The ``only`` parameter now freely supports joins independent of the main query. | ||
| 137 | - Adds support for alias relabeling permitting excludes and updates with aggregates filtered on remote foreign key relations. | ||
| 138 | |||
| 139 | 0.3.1 | ||
| 140 | - Fix quotation escaping. | ||
| 141 | - Fix boolean casts on Postgres. | ||
| 142 | |||
| 143 | 0.2 | ||
| 144 | - Fix postgres issue with LIKE conditions. | ||
| 145 | |||
| 146 | 0.1 | ||
| 147 | - Initial release. | ||
| 148 | |||
| 149 | |||
| 150 | License | ||
| 151 | ======= | ||
| 152 | |||
| 153 | The MIT License. | ||
| 154 | |||
| 155 | .. _ticket 11305: https://code.djangoproject.com/ticket/11305 | ||
| 156 | .. _first issue: https://github.com/henriquebastos/django-aggregate-if/issues/1 | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/aggregate_if.py b/bitbake/lib/toaster/contrib/django-aggregate-if-master/aggregate_if.py deleted file mode 100644 index d5f3427170..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/aggregate_if.py +++ /dev/null | |||
| @@ -1,164 +0,0 @@ | |||
| 1 | # coding: utf-8 | ||
| 2 | ''' | ||
| 3 | Implements conditional aggregates. | ||
| 4 | |||
| 5 | This code was based on the work of others found on the internet: | ||
| 6 | |||
| 7 | 1. http://web.archive.org/web/20101115170804/http://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django | ||
| 8 | 2. https://code.djangoproject.com/ticket/11305 | ||
| 9 | 3. https://groups.google.com/forum/?fromgroups=#!topic/django-users/cjzloTUwmS0 | ||
| 10 | 4. https://groups.google.com/forum/?fromgroups=#!topic/django-users/vVprMpsAnPo | ||
| 11 | ''' | ||
| 12 | from __future__ import unicode_literals | ||
| 13 | from django.utils import six | ||
| 14 | import django | ||
| 15 | from django.db.models.aggregates import Aggregate as DjangoAggregate | ||
| 16 | from django.db.models.sql.aggregates import Aggregate as DjangoSqlAggregate | ||
| 17 | |||
| 18 | |||
| 19 | VERSION = django.VERSION[:2] | ||
| 20 | |||
| 21 | |||
| 22 | class SqlAggregate(DjangoSqlAggregate): | ||
| 23 | conditional_template = '%(function)s(CASE WHEN %(condition)s THEN %(field)s ELSE null END)' | ||
| 24 | |||
| 25 | def __init__(self, col, source=None, is_summary=False, condition=None, **extra): | ||
| 26 | super(SqlAggregate, self).__init__(col, source, is_summary, **extra) | ||
| 27 | self.condition = condition | ||
| 28 | |||
| 29 | def relabel_aliases(self, change_map): | ||
| 30 | if VERSION < (1, 7): | ||
| 31 | super(SqlAggregate, self).relabel_aliases(change_map) | ||
| 32 | if self.has_condition: | ||
| 33 | condition_change_map = dict((k, v) for k, v in \ | ||
| 34 | change_map.items() if k in self.condition.query.alias_map | ||
| 35 | ) | ||
| 36 | self.condition.query.change_aliases(condition_change_map) | ||
| 37 | |||
| 38 | def relabeled_clone(self, change_map): | ||
| 39 | self.relabel_aliases(change_map) | ||
| 40 | return super(SqlAggregate, self).relabeled_clone(change_map) | ||
| 41 | |||
| 42 | def as_sql(self, qn, connection): | ||
| 43 | if self.has_condition: | ||
| 44 | self.sql_template = self.conditional_template | ||
| 45 | self.extra['condition'] = self._condition_as_sql(qn, connection) | ||
| 46 | |||
| 47 | return super(SqlAggregate, self).as_sql(qn, connection) | ||
| 48 | |||
| 49 | @property | ||
| 50 | def has_condition(self): | ||
| 51 | # Warning: bool(QuerySet) will hit the database | ||
| 52 | return self.condition is not None | ||
| 53 | |||
| 54 | def _condition_as_sql(self, qn, connection): | ||
| 55 | ''' | ||
| 56 | Return sql for condition. | ||
| 57 | ''' | ||
| 58 | def escape(value): | ||
| 59 | if isinstance(value, bool): | ||
| 60 | value = str(int(value)) | ||
| 61 | if isinstance(value, six.string_types): | ||
| 62 | # Escape params used with LIKE | ||
| 63 | if '%' in value: | ||
| 64 | value = value.replace('%', '%%') | ||
| 65 | # Escape single quotes | ||
| 66 | if "'" in value: | ||
| 67 | value = value.replace("'", "''") | ||
| 68 | # Add single quote to text values | ||
| 69 | value = "'" + value + "'" | ||
| 70 | return value | ||
| 71 | |||
| 72 | sql, param = self.condition.query.where.as_sql(qn, connection) | ||
| 73 | param = map(escape, param) | ||
| 74 | |||
| 75 | return sql % tuple(param) | ||
| 76 | |||
| 77 | |||
| 78 | class SqlSum(SqlAggregate): | ||
| 79 | sql_function = 'SUM' | ||
| 80 | |||
| 81 | |||
| 82 | class SqlCount(SqlAggregate): | ||
| 83 | is_ordinal = True | ||
| 84 | sql_function = 'COUNT' | ||
| 85 | sql_template = '%(function)s(%(distinct)s%(field)s)' | ||
| 86 | conditional_template = '%(function)s(%(distinct)sCASE WHEN %(condition)s THEN %(field)s ELSE null END)' | ||
| 87 | |||
| 88 | def __init__(self, col, distinct=False, **extra): | ||
| 89 | super(SqlCount, self).__init__(col, distinct=distinct and 'DISTINCT ' or '', **extra) | ||
| 90 | |||
| 91 | |||
| 92 | class SqlAvg(SqlAggregate): | ||
| 93 | is_computed = True | ||
| 94 | sql_function = 'AVG' | ||
| 95 | |||
| 96 | |||
| 97 | class SqlMax(SqlAggregate): | ||
| 98 | sql_function = 'MAX' | ||
| 99 | |||
| 100 | |||
| 101 | class SqlMin(SqlAggregate): | ||
| 102 | sql_function = 'MIN' | ||
| 103 | |||
| 104 | |||
| 105 | class Aggregate(DjangoAggregate): | ||
| 106 | def __init__(self, lookup, only=None, **extra): | ||
| 107 | super(Aggregate, self).__init__(lookup, **extra) | ||
| 108 | self.only = only | ||
| 109 | self.condition = None | ||
| 110 | |||
| 111 | def _get_fields_from_Q(self, q): | ||
| 112 | fields = [] | ||
| 113 | for child in q.children: | ||
| 114 | if hasattr(child, 'children'): | ||
| 115 | fields.extend(self._get_fields_from_Q(child)) | ||
| 116 | else: | ||
| 117 | fields.append(child) | ||
| 118 | return fields | ||
| 119 | |||
| 120 | def add_to_query(self, query, alias, col, source, is_summary): | ||
| 121 | if self.only: | ||
| 122 | self.condition = query.model._default_manager.filter(self.only) | ||
| 123 | for child in self._get_fields_from_Q(self.only): | ||
| 124 | field_list = child[0].split('__') | ||
| 125 | # Pop off the last field if it's a query term ('gte', 'contains', 'isnull', etc.) | ||
| 126 | if field_list[-1] in query.query_terms: | ||
| 127 | field_list.pop() | ||
| 128 | # setup_joins have different returns in Django 1.5 and 1.6, but the order of what we need remains. | ||
| 129 | result = query.setup_joins(field_list, query.model._meta, query.get_initial_alias(), None) | ||
| 130 | join_list = result[3] | ||
| 131 | |||
| 132 | fname = 'promote_alias_chain' if VERSION < (1, 5) else 'promote_joins' | ||
| 133 | args = (join_list, True) if VERSION < (1, 7) else (join_list,) | ||
| 134 | |||
| 135 | promote = getattr(query, fname) | ||
| 136 | promote(*args) | ||
| 137 | |||
| 138 | aggregate = self.sql_klass(col, source=source, is_summary=is_summary, condition=self.condition, **self.extra) | ||
| 139 | query.aggregates[alias] = aggregate | ||
| 140 | |||
| 141 | |||
| 142 | class Sum(Aggregate): | ||
| 143 | name = 'Sum' | ||
| 144 | sql_klass = SqlSum | ||
| 145 | |||
| 146 | |||
| 147 | class Count(Aggregate): | ||
| 148 | name = 'Count' | ||
| 149 | sql_klass = SqlCount | ||
| 150 | |||
| 151 | |||
| 152 | class Avg(Aggregate): | ||
| 153 | name = 'Avg' | ||
| 154 | sql_klass = SqlAvg | ||
| 155 | |||
| 156 | |||
| 157 | class Max(Aggregate): | ||
| 158 | name = 'Max' | ||
| 159 | sql_klass = SqlMax | ||
| 160 | |||
| 161 | |||
| 162 | class Min(Aggregate): | ||
| 163 | name = 'Min' | ||
| 164 | sql_klass = SqlMin | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/runtests.py b/bitbake/lib/toaster/contrib/django-aggregate-if-master/runtests.py deleted file mode 100755 index 2e55864e3a..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/runtests.py +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | #!/usr/bin/env python | ||
| 2 | |||
| 3 | import os | ||
| 4 | import sys | ||
| 5 | from optparse import OptionParser | ||
| 6 | |||
| 7 | |||
| 8 | def parse_args(): | ||
| 9 | parser = OptionParser() | ||
| 10 | parser.add_option('-s', '--settings', help='Define settings.') | ||
| 11 | parser.add_option('-t', '--unittest', help='Define which test to run. Default all.') | ||
| 12 | options, args = parser.parse_args() | ||
| 13 | |||
| 14 | if not options.settings: | ||
| 15 | parser.print_help() | ||
| 16 | sys.exit(1) | ||
| 17 | |||
| 18 | if not options.unittest: | ||
| 19 | options.unittest = ['aggregation'] | ||
| 20 | |||
| 21 | return options | ||
| 22 | |||
| 23 | |||
| 24 | def get_runner(settings_module): | ||
| 25 | ''' | ||
| 26 | Asks Django for the TestRunner defined in settings or the default one. | ||
| 27 | ''' | ||
| 28 | os.environ['DJANGO_SETTINGS_MODULE'] = settings_module | ||
| 29 | |||
| 30 | import django | ||
| 31 | from django.test.utils import get_runner | ||
| 32 | from django.conf import settings | ||
| 33 | |||
| 34 | if hasattr(django, 'setup'): | ||
| 35 | django.setup() | ||
| 36 | |||
| 37 | return get_runner(settings) | ||
| 38 | |||
| 39 | |||
| 40 | def runtests(): | ||
| 41 | options = parse_args() | ||
| 42 | TestRunner = get_runner(options.settings) | ||
| 43 | runner = TestRunner(verbosity=1, interactive=True, failfast=False) | ||
| 44 | sys.exit(runner.run_tests([])) | ||
| 45 | |||
| 46 | |||
| 47 | if __name__ == '__main__': | ||
| 48 | runtests() | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/setup.py b/bitbake/lib/toaster/contrib/django-aggregate-if-master/setup.py deleted file mode 100644 index aed3db14d1..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/setup.py +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | # coding: utf-8 | ||
| 2 | from setuptools import setup | ||
| 3 | import os | ||
| 4 | |||
| 5 | |||
| 6 | setup(name='django-aggregate-if', | ||
| 7 | version='0.5', | ||
| 8 | description='Conditional aggregates for Django, just like the famous SumIf in Excel.', | ||
| 9 | long_description=open(os.path.join(os.path.dirname(__file__), "README.rst")).read(), | ||
| 10 | author="Henrique Bastos", author_email="henrique@bastos.net", | ||
| 11 | license="MIT", | ||
| 12 | py_modules=['aggregate_if'], | ||
| 13 | install_requires=[ | ||
| 14 | 'six>=1.6.1', | ||
| 15 | ], | ||
| 16 | zip_safe=False, | ||
| 17 | platforms='any', | ||
| 18 | include_package_data=True, | ||
| 19 | classifiers=[ | ||
| 20 | 'Development Status :: 5 - Production/Stable', | ||
| 21 | 'Framework :: Django', | ||
| 22 | 'Intended Audience :: Developers', | ||
| 23 | 'License :: OSI Approved :: MIT License', | ||
| 24 | 'Natural Language :: English', | ||
| 25 | 'Operating System :: OS Independent', | ||
| 26 | 'Programming Language :: Python', | ||
| 27 | 'Programming Language :: Python :: 2.7', | ||
| 28 | 'Programming Language :: Python :: 3', | ||
| 29 | 'Topic :: Database', | ||
| 30 | 'Topic :: Software Development :: Libraries', | ||
| 31 | ], | ||
| 32 | url='http://github.com/henriquebastos/django-aggregate-if/', | ||
| 33 | ) | ||
diff --git a/bitbake/lib/toaster/contrib/django-aggregate-if-master/tox.ini b/bitbake/lib/toaster/contrib/django-aggregate-if-master/tox.ini deleted file mode 100644 index 78beb148aa..0000000000 --- a/bitbake/lib/toaster/contrib/django-aggregate-if-master/tox.ini +++ /dev/null | |||
| @@ -1,198 +0,0 @@ | |||
| 1 | [tox] | ||
| 2 | envlist = | ||
| 3 | py27-django1.4-sqlite, | ||
| 4 | py27-django1.4-postgres, | ||
| 5 | py27-django1.4-mysql, | ||
| 6 | |||
| 7 | py27-django1.5-sqlite, | ||
| 8 | py27-django1.5-postgres, | ||
| 9 | py27-django1.5-mysql, | ||
| 10 | |||
| 11 | py27-django1.6-sqlite, | ||
| 12 | py27-django1.6-postgres, | ||
| 13 | py27-django1.6-mysql, | ||
| 14 | |||
| 15 | py27-django1.7-sqlite, | ||
| 16 | py27-django1.7-postgres, | ||
| 17 | py27-django1.7-mysql, | ||
| 18 | |||
| 19 | py34-django1.6-sqlite, | ||
| 20 | py34-django1.6-postgres, | ||
| 21 | #py34-django1.6-mysql | ||
| 22 | |||
| 23 | py34-django1.7-sqlite, | ||
| 24 | py34-django1.7-postgres, | ||
| 25 | #py34-django1.7-mysql | ||
| 26 | |||
| 27 | [testenv] | ||
| 28 | whitelist_externals= | ||
| 29 | mysql | ||
| 30 | psql | ||
| 31 | |||
| 32 | # Python 2.7 | ||
| 33 | # Django 1.4 | ||
| 34 | [testenv:py27-django1.4-sqlite] | ||
| 35 | basepython = python2.7 | ||
| 36 | deps = | ||
| 37 | django==1.4 | ||
| 38 | commands = python runtests.py --settings tests.test_sqlite | ||
| 39 | |||
| 40 | [testenv:py27-django1.4-postgres] | ||
| 41 | basepython = python2.7 | ||
| 42 | deps = | ||
| 43 | django==1.4 | ||
| 44 | psycopg2 | ||
| 45 | commands = | ||
| 46 | psql -c 'create database aggregation;' postgres | ||
| 47 | python runtests.py --settings tests.test_postgres | ||
| 48 | psql -c 'drop database aggregation;' postgres | ||
| 49 | |||
| 50 | [testenv:py27-django1.4-mysql] | ||
| 51 | basepython = python2.7 | ||
| 52 | deps = | ||
| 53 | django==1.4 | ||
| 54 | mysql-python | ||
| 55 | commands = | ||
| 56 | mysql -e 'create database aggregation;' | ||
| 57 | python runtests.py --settings tests.test_mysql | ||
| 58 | mysql -e 'drop database aggregation;' | ||
| 59 | |||
| 60 | # Django 1.5 | ||
| 61 | [testenv:py27-django1.5-sqlite] | ||
| 62 | basepython = python2.7 | ||
| 63 | deps = | ||
| 64 | django==1.5 | ||
| 65 | commands = python runtests.py --settings tests.test_sqlite | ||
| 66 | |||
| 67 | [testenv:py27-django1.5-postgres] | ||
| 68 | basepython = python2.7 | ||
| 69 | deps = | ||
| 70 | django==1.5 | ||
| 71 | psycopg2 | ||
| 72 | commands = | ||
| 73 | psql -c 'create database aggregation;' postgres | ||
| 74 | python runtests.py --settings tests.test_postgres | ||
| 75 | psql -c 'drop database aggregation;' postgres | ||
| 76 | |||
| 77 | [testenv:py27-django1.5-mysql] | ||
| 78 | basepython = python2.7 | ||
| 79 | deps = | ||
| 80 | django==1.5 | ||
| 81 | mysql-python | ||
| 82 | commands = | ||
| 83 | mysql -e 'create database aggregation;' | ||
| 84 | python runtests.py --settings tests.test_mysql | ||
| 85 | mysql -e 'drop database aggregation;' | ||
| 86 | |||
| 87 | # Django 1.6 | ||
| 88 | [testenv:py27-django1.6-sqlite] | ||
| 89 | basepython = python2.7 | ||
| 90 | deps = | ||
| 91 | django==1.6 | ||
| 92 | commands = python runtests.py --settings tests.test_sqlite | ||
| 93 | |||
| 94 | [testenv:py27-django1.6-postgres] | ||
| 95 | basepython = python2.7 | ||
| 96 | deps = | ||
| 97 | django==1.6 | ||
| 98 | psycopg2 | ||
| 99 | commands = | ||
| 100 | psql -c 'create database aggregation;' postgres | ||
| 101 | python runtests.py --settings tests.test_postgres | ||
| 102 | psql -c 'drop database aggregation;' postgres | ||
| 103 | |||
| 104 | [testenv:py27-django1.6-mysql] | ||
| 105 | basepython = python2.7 | ||
| 106 | deps = | ||
| 107 | django==1.6 | ||
| 108 | mysql-python | ||
| 109 | commands = | ||
| 110 | mysql -e 'create database aggregation;' | ||
| 111 | python runtests.py --settings tests.test_mysql | ||
| 112 | mysql -e 'drop database aggregation;' | ||
| 113 | |||
| 114 | |||
| 115 | # Python 2.7 and Django 1.7 | ||
| 116 | [testenv:py27-django1.7-sqlite] | ||
| 117 | basepython = python2.7 | ||
| 118 | deps = | ||
| 119 | django==1.7 | ||
| 120 | commands = python runtests.py --settings tests.test_sqlite | ||
| 121 | |||
| 122 | [testenv:py27-django1.7-postgres] | ||
| 123 | basepython = python2.7 | ||
| 124 | deps = | ||
| 125 | django==1.7 | ||
| 126 | psycopg2 | ||
| 127 | commands = | ||
| 128 | psql -c 'create database aggregation;' postgres | ||
| 129 | python runtests.py --settings tests.test_postgres | ||
| 130 | psql -c 'drop database aggregation;' postgres | ||
| 131 | |||
| 132 | [testenv:py27-django1.7-mysql] | ||
| 133 | basepython = python2.7 | ||
| 134 | deps = | ||
| 135 | django==1.7 | ||
| 136 | mysql-python | ||
| 137 | commands = | ||
| 138 | mysql -e 'create database aggregation;' | ||
| 139 | python runtests.py --settings tests.test_mysql | ||
| 140 | mysql -e 'drop database aggregation;' | ||
| 141 | |||
| 142 | |||
| 143 | # Python 3.4 | ||
| 144 | # Django 1.6 | ||
| 145 | [testenv:py34-django1.6-sqlite] | ||
| 146 | basepython = python3.4 | ||
| 147 | deps = | ||
| 148 | django==1.6 | ||
| 149 | commands = python runtests.py --settings tests.test_sqlite | ||
| 150 | |||
| 151 | [testenv:py34-django1.6-postgres] | ||
| 152 | basepython = python3.4 | ||
| 153 | deps = | ||
| 154 | django==1.6 | ||
| 155 | psycopg2 | ||
| 156 | commands = | ||
| 157 | psql -c 'create database aggregation;' postgres | ||
| 158 | python runtests.py --settings tests.test_postgres | ||
| 159 | psql -c 'drop database aggregation;' postgres | ||
| 160 | |||
| 161 | [testenv:py34-django1.6-mysql] | ||
| 162 | basepython = python3.4 | ||
| 163 | deps = | ||
| 164 | django==1.6 | ||
| 165 | mysql-python3 | ||
| 166 | commands = | ||
| 167 | mysql -e 'create database aggregation;' | ||
| 168 | python runtests.py --settings tests.test_mysql | ||
| 169 | mysql -e 'drop database aggregation;' | ||
| 170 | |||
| 171 | |||
| 172 | # Python 3.4 | ||
| 173 | # Django 1.7 | ||
| 174 | [testenv:py34-django1.7-sqlite] | ||
| 175 | basepython = python3.4 | ||
| 176 | deps = | ||
| 177 | django==1.7 | ||
| 178 | commands = python runtests.py --settings tests.test_sqlite | ||
| 179 | |||
| 180 | [testenv:py34-django1.7-postgres] | ||
| 181 | basepython = python3.4 | ||
| 182 | deps = | ||
| 183 | django==1.7 | ||
| 184 | psycopg2 | ||
| 185 | commands = | ||
| 186 | psql -c 'create database aggregation;' postgres | ||
| 187 | python runtests.py --settings tests.test_postgres | ||
| 188 | psql -c 'drop database aggregation;' postgres | ||
| 189 | |||
| 190 | [testenv:py34-django1.7-mysql] | ||
| 191 | basepython = python3.4 | ||
| 192 | deps = | ||
| 193 | django==1.7 | ||
| 194 | mysql-python3 | ||
| 195 | commands = | ||
| 196 | mysql -e 'create database aggregation;' | ||
| 197 | python runtests.py --settings tests.test_mysql | ||
| 198 | mysql -e 'drop database aggregation;' | ||
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py index 14077e10ae..227973114c 100644 --- a/bitbake/lib/toaster/toastergui/tables.py +++ b/bitbake/lib/toaster/toastergui/tables.py | |||
| @@ -23,7 +23,7 @@ from toastergui.widgets import ToasterTable | |||
| 23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project | 23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project |
| 24 | from orm.models import CustomImageRecipe, Package, Build, LogMessage, Task | 24 | from orm.models import CustomImageRecipe, Package, Build, LogMessage, Task |
| 25 | from orm.models import ProjectTarget | 25 | from orm.models import ProjectTarget |
| 26 | from django.db.models import Q, Max, Count | 26 | from django.db.models import Q, Max, Count, When, Case, Value, IntegerField |
| 27 | from django.conf.urls import url | 27 | from django.conf.urls import url |
| 28 | from django.core.urlresolvers import reverse, resolve | 28 | from django.core.urlresolvers import reverse, resolve |
| 29 | from django.http import HttpResponse | 29 | from django.http import HttpResponse |
| @@ -927,6 +927,13 @@ class BuildsTable(ToasterTable): | |||
| 927 | return context | 927 | return context |
| 928 | 928 | ||
| 929 | def setup_queryset(self, *args, **kwargs): | 929 | def setup_queryset(self, *args, **kwargs): |
| 930 | """ | ||
| 931 | The queryset is annotated so that it can be sorted by number of | ||
| 932 | errors and number of warnings; but note that the criteria for | ||
| 933 | finding the log messages to populate these fields should match those | ||
| 934 | used in the Build model (orm/models.py) to populate the errors and | ||
| 935 | warnings properties | ||
| 936 | """ | ||
| 930 | queryset = self.get_builds() | 937 | queryset = self.get_builds() |
| 931 | 938 | ||
| 932 | # don't include in progress builds | 939 | # don't include in progress builds |
| @@ -935,20 +942,27 @@ class BuildsTable(ToasterTable): | |||
| 935 | # sort | 942 | # sort |
| 936 | queryset = queryset.order_by(self.default_orderby) | 943 | queryset = queryset.order_by(self.default_orderby) |
| 937 | 944 | ||
| 938 | # annotate with number of ERROR and EXCEPTION log messages | 945 | # annotate with number of ERROR, EXCEPTION and CRITICAL log messages |
| 946 | criteria = (Q(logmessage__level=LogMessage.ERROR) | | ||
| 947 | Q(logmessage__level=LogMessage.EXCEPTION) | | ||
| 948 | Q(logmessage__level=LogMessage.CRITICAL)) | ||
| 949 | |||
| 939 | queryset = queryset.annotate( | 950 | queryset = queryset.annotate( |
| 940 | errors_no = Count( | 951 | errors_no=Count( |
| 941 | 'logmessage', | 952 | Case( |
| 942 | only = Q(logmessage__level=LogMessage.ERROR) | | 953 | When(criteria, then=Value(1)), |
| 943 | Q(logmessage__level=LogMessage.EXCEPTION) | 954 | output_field=IntegerField() |
| 955 | ) | ||
| 944 | ) | 956 | ) |
| 945 | ) | 957 | ) |
| 946 | 958 | ||
| 947 | # annotate with number of WARNING log messages | 959 | # annotate with number of WARNING log messages |
| 948 | queryset = queryset.annotate( | 960 | queryset = queryset.annotate( |
| 949 | warnings_no = Count( | 961 | warnings_no=Count( |
| 950 | 'logmessage', | 962 | Case( |
| 951 | only = Q(logmessage__level=LogMessage.WARNING) | 963 | When(logmessage__level=LogMessage.WARNING, then=Value(1)), |
| 964 | output_field=IntegerField() | ||
| 965 | ) | ||
| 952 | ) | 966 | ) |
| 953 | ) | 967 | ) |
| 954 | 968 | ||
| @@ -1020,17 +1034,17 @@ class BuildsTable(ToasterTable): | |||
| 1020 | ''' | 1034 | ''' |
| 1021 | 1035 | ||
| 1022 | errors_template = ''' | 1036 | errors_template = ''' |
| 1023 | {% if data.errors.count %} | 1037 | {% if data.errors_no %} |
| 1024 | <a class="errors.count error" href="{% url "builddashboard" data.id %}#errors"> | 1038 | <a class="errors.count error" href="{% url "builddashboard" data.id %}#errors"> |
| 1025 | {{data.errors.count}} error{{data.errors.count|pluralize}} | 1039 | {{data.errors_no}} error{{data.errors_no|pluralize}} |
| 1026 | </a> | 1040 | </a> |
| 1027 | {% endif %} | 1041 | {% endif %} |
| 1028 | ''' | 1042 | ''' |
| 1029 | 1043 | ||
| 1030 | warnings_template = ''' | 1044 | warnings_template = ''' |
| 1031 | {% if data.warnings.count %} | 1045 | {% if data.warnings_no %} |
| 1032 | <a class="warnings.count warning" href="{% url "builddashboard" data.id %}#warnings"> | 1046 | <a class="warnings.count warning" href="{% url "builddashboard" data.id %}#warnings"> |
| 1033 | {{data.warnings.count}} warning{{data.warnings.count|pluralize}} | 1047 | {{data.warnings_no}} warning{{data.warnings_no|pluralize}} |
| 1034 | </a> | 1048 | </a> |
| 1035 | {% endif %} | 1049 | {% endif %} |
| 1036 | ''' | 1050 | ''' |
diff --git a/bitbake/lib/toaster/toastermain/settings.py b/bitbake/lib/toaster/toastermain/settings.py index 74103f3063..c4f3d6bfff 100644 --- a/bitbake/lib/toaster/toastermain/settings.py +++ b/bitbake/lib/toaster/toastermain/settings.py | |||
| @@ -399,12 +399,3 @@ class InvalidString(str): | |||
| 399 | "Undefined variable or unknown value for: \"%s\"" % other) | 399 | "Undefined variable or unknown value for: \"%s\"" % other) |
| 400 | 400 | ||
| 401 | TEMPLATE_STRING_IF_INVALID = InvalidString("%s") | 401 | TEMPLATE_STRING_IF_INVALID = InvalidString("%s") |
| 402 | |||
| 403 | import sys | ||
| 404 | sys.path.append( | ||
| 405 | os.path.join( | ||
| 406 | os.path.join( | ||
| 407 | os.path.dirname(os.path.dirname(os.path.abspath(__file__))), | ||
| 408 | "contrib"), | ||
| 409 | "django-aggregate-if-master") | ||
| 410 | ) | ||
