Commit ee69bd3a7f847b2f882d36b88d2a467e4a97116e
Exists in
master
and in
39 other branches
Merge branch 'master' of github.com:TracyWebTech/colab
Showing
17 changed files
with
695 additions
and
104 deletions
Show diff stats
TODO.rst
requirements.txt
src/accounts/migrations/0006_auto__add_field_user_modified.py
0 → 100644
... | ... | @@ -0,0 +1,69 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | +from south.db import db | |
3 | +from south.v2 import SchemaMigration | |
4 | +from django.db import models | |
5 | +from django.utils import timezone | |
6 | + | |
7 | + | |
8 | +class Migration(SchemaMigration): | |
9 | + | |
10 | + def forwards(self, orm): | |
11 | + # Adding field 'User.modified' | |
12 | + db.add_column(u'accounts_user', 'modified', | |
13 | + self.gf('django.db.models.fields.DateTimeField')(auto_now=True, default=timezone.now, blank=True), | |
14 | + keep_default=False) | |
15 | + | |
16 | + | |
17 | + def backwards(self, orm): | |
18 | + # Deleting field 'User.modified' | |
19 | + db.delete_column(u'accounts_user', 'modified') | |
20 | + | |
21 | + | |
22 | + models = { | |
23 | + u'accounts.user': { | |
24 | + 'Meta': {'object_name': 'User'}, | |
25 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
26 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | |
27 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
28 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
29 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | |
30 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | |
31 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
32 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
33 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
34 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
35 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
36 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
37 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
38 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), | |
39 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | |
40 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
41 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
42 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | |
43 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | |
44 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | |
45 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | |
46 | + }, | |
47 | + u'auth.group': { | |
48 | + 'Meta': {'object_name': 'Group'}, | |
49 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
50 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | |
51 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | |
52 | + }, | |
53 | + u'auth.permission': { | |
54 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | |
55 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
56 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | |
57 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
58 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
59 | + }, | |
60 | + u'contenttypes.contenttype': { | |
61 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | |
62 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
63 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
64 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
65 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | |
66 | + } | |
67 | + } | |
68 | + | |
69 | + complete_apps = ['accounts'] | ... | ... |
src/accounts/models.py
... | ... | @@ -16,6 +16,7 @@ class User(AbstractUser): |
16 | 16 | google_talk = models.EmailField(null=True, blank=True) |
17 | 17 | webpage = models.CharField(max_length=256, null=True, blank=True) |
18 | 18 | verification_hash = models.CharField(max_length=32, null=True, blank=True) |
19 | + modified = models.DateTimeField(auto_now=True) | |
19 | 20 | |
20 | 21 | def get_absolute_url(self): |
21 | 22 | return reverse('user_profile', kwargs={'username': self.username}) | ... | ... |
src/accounts/search_indexes.py
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | |
3 | 3 | from haystack import indexes |
4 | +from django.db.models import Count | |
4 | 5 | |
6 | +from proxy.models import Revision, Ticket, Wiki | |
7 | +from badger.utils import get_users_counters | |
5 | 8 | from .models import User |
6 | 9 | |
7 | 10 | |
8 | 11 | class UserIndex(indexes.SearchIndex, indexes.Indexable): |
9 | 12 | # common fields |
10 | - text = indexes.CharField(document=True, use_template=True) | |
11 | - url = indexes.CharField(model_attr='get_absolute_url') | |
13 | + text = indexes.CharField(document=True, use_template=True, stored=False) | |
14 | + url = indexes.CharField(model_attr='get_absolute_url', indexed=False) | |
12 | 15 | title = indexes.CharField(model_attr='get_full_name') |
13 | 16 | description = indexes.CharField(null=True) |
14 | 17 | type = indexes.CharField() |
15 | 18 | icon_name = indexes.CharField() |
16 | 19 | |
17 | 20 | # extra fields |
18 | - username = indexes.CharField(model_attr='username') | |
21 | + username = indexes.CharField(model_attr='username', stored=False) | |
19 | 22 | name = indexes.CharField(model_attr='get_full_name') |
20 | - email = indexes.CharField(model_attr='email') | |
23 | + email = indexes.CharField(model_attr='email', stored=False) | |
21 | 24 | institution = indexes.CharField(model_attr='institution', null=True) |
22 | 25 | role = indexes.CharField(model_attr='role', null=True) |
23 | - google_talk = indexes.CharField(model_attr='google_talk', null=True) | |
24 | - webpage = indexes.CharField(model_attr='webpage', null=True) | |
26 | + google_talk = indexes.CharField(model_attr='google_talk', null=True, | |
27 | + stored=False) | |
28 | + webpage = indexes.CharField(model_attr='webpage', null=True, stored=False) | |
29 | + message_count = indexes.IntegerField(stored=False) | |
30 | + changeset_count = indexes.IntegerField(stored=False) | |
31 | + ticket_count = indexes.IntegerField(stored=False) | |
32 | + wiki_count = indexes.IntegerField(stored=False) | |
33 | + contribution_count = indexes.IntegerField(stored=False) | |
25 | 34 | |
26 | 35 | def get_model(self): |
27 | 36 | return User |
28 | 37 | |
38 | + @property | |
39 | + def badge_counters(self): | |
40 | + if not hasattr(self, '_badge_counters'): | |
41 | + self._badge_counters = get_users_counters() | |
42 | + return self._badge_counters | |
43 | + | |
29 | 44 | def get_updated_field(self): |
30 | - return 'date_joined' | |
45 | + return 'modified' | |
46 | + | |
47 | + def prepare(self, obj): | |
48 | + prepared_data = super(UserIndex, self).prepare(obj) | |
49 | + | |
50 | + prepared_data['contribution_count'] = sum(( | |
51 | + self.prepared_data['message_count'], | |
52 | + self.prepared_data['changeset_count'], | |
53 | + self.prepared_data['ticket_count'], | |
54 | + self.prepared_data['wiki_count'] | |
55 | + )) | |
56 | + | |
57 | + return prepared_data | |
31 | 58 | |
32 | 59 | def prepare_description(self, obj): |
33 | 60 | return u'{}\n{}\n{}\n{}'.format( |
... | ... | @@ -40,5 +67,17 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable): |
40 | 67 | def prepare_type(self, obj): |
41 | 68 | return u'user' |
42 | 69 | |
70 | + def prepare_message_count(self, obj): | |
71 | + return self.badge_counters[obj.username]['messages'] | |
72 | + | |
73 | + def prepare_changeset_count(self, obj): | |
74 | + return self.badge_counters[obj.username]['revisions'] | |
75 | + | |
76 | + def prepare_ticket_count(self, obj): | |
77 | + return self.badge_counters[obj.username]['tickets'] | |
78 | + | |
79 | + def prepare_wiki_count(self, obj): | |
80 | + return self.badge_counters[obj.username]['wikis'] | |
81 | + | |
43 | 82 | def index_queryset(self, using=None): |
44 | 83 | return self.get_model().objects.filter(is_active=True) | ... | ... |
src/accounts/templates/accounts/user_detail.html
1 | 1 | {% extends "base.html" %} |
2 | -{% load i18n gravatar %} | |
2 | + | |
3 | +{% load i18n gravatar i18n_model %} | |
4 | + | |
3 | 5 | |
4 | 6 | {% block head_js %} |
5 | 7 | {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=300 %} |
... | ... | @@ -36,40 +38,41 @@ |
36 | 38 | |
37 | 39 | <ul class="unstyled-list"> |
38 | 40 | {% if user_.institution or user_.role %} |
39 | - <li> | |
40 | - <span class="icon-briefcase icon-fixed-width"></span> | |
41 | - {{ user_.role }} | |
42 | - {% if user_.institution and user_.role %}-{% endif %} | |
43 | - {{ user_.institution }} | |
44 | - </li> | |
45 | - {% endif %} | |
46 | - {% if request.user.is_active %} | |
47 | - <li> | |
48 | - {% if user_.twitter %} | |
49 | - <span class="icon-twitter icon-fixed-width"></span> <a target="_blank" href="{{ user_.twitter_link }}" title="{% trans 'Twitter account' %}">{{ user_.twitter }}</a> | |
50 | - {% endif %} | |
51 | - {% if user_.facebook %} | |
52 | - <span class="icon-facebook icon-fixed-width"></span> <a target="_blank" href="{{ user_.facebook_link }}" title="{% trans 'Facebook account' %}">{{ user_.facebook }}</a> | |
53 | - {% endif %} | |
54 | - </li> | |
55 | - | |
56 | - {% if user_.google_talk %} | |
57 | - <li><span class="icon-google-plus icon-fixed-width"></span> {{ user_.google_talk }}</li> | |
41 | + <li> | |
42 | + <span class="icon-briefcase icon-fixed-width"></span> | |
43 | + {{ user_.role }} | |
44 | + {% if user_.institution and user_.role %}-{% endif %} | |
45 | + {{ user_.institution }} | |
46 | + </li> | |
58 | 47 | {% endif %} |
59 | - {% if user_.webpage %} | |
60 | - <li><span class="icon-link icon-fixed-width"></span> <a target="_blank" href="{{ user_.webpage }}" title="{% trans 'Personal webpage' %}">{{ user_.webpage }}</a></li> | |
48 | + {% if request.user.is_active %} | |
49 | + <li> | |
50 | + {% if user_.twitter %} | |
51 | + <span class="icon-twitter icon-fixed-width"></span> <a target="_blank" href="{{ user_.twitter_link }}" title="{% trans 'Twitter account' %}">{{ user_.twitter }}</a> | |
52 | + {% endif %} | |
53 | + {% if user_.facebook %} | |
54 | + <span class="icon-facebook icon-fixed-width"></span> <a target="_blank" href="{{ user_.facebook_link }}" title="{% trans 'Facebook account' %}">{{ user_.facebook }}</a> | |
55 | + {% endif %} | |
56 | + </li> | |
57 | + | |
58 | + {% if user_.google_talk %} | |
59 | + <li><span class="icon-google-plus icon-fixed-width"></span> {{ user_.google_talk }}</li> | |
60 | + {% endif %} | |
61 | + {% if user_.webpage %} | |
62 | + <li><span class="icon-link icon-fixed-width"></span> <a target="_blank" href="{{ user_.webpage }}" title="{% trans 'Personal webpage' %}">{{ user_.webpage }}</a></li> | |
63 | + {% endif %} | |
61 | 64 | {% endif %} |
62 | - {% endif %} | |
63 | 65 | </ul> |
64 | 66 | |
65 | 67 | {% if user_.mailinglists %} |
66 | - <b>{% trans 'Subscribes: ' %}</b> | |
68 | + <b>{% trans 'Subscribes: ' %}</b> | |
67 | 69 | {% for list in user_.mailinglists %} |
68 | 70 | <span class="label label-primary">{{ list }}</span> |
69 | 71 | {% endfor %} |
70 | 72 | {% endif %} |
71 | 73 | |
72 | 74 | <div class="divider"></div> |
75 | + | |
73 | 76 | </div> |
74 | 77 | |
75 | 78 | <div class="col-lg-4 col-md-4 col-sm-7"> |
... | ... | @@ -95,29 +98,50 @@ |
95 | 98 | </div> |
96 | 99 | </div> |
97 | 100 | |
98 | - </div> | |
99 | - <div class="row"> | |
100 | - <div class="col-lg-6 col-md-6 col-sm-12"> | |
101 | - <h3>{% trans "Latest posted" %} </h3> | |
102 | - <ul class="message-list"> | |
103 | - {% for doc in emails %} | |
104 | - {% include "message-preview.html" with result=doc %} | |
105 | - {% empty %} | |
106 | - <li>{% trans "There are no posts by this user so far." %}</li> | |
107 | - {% endfor %} | |
108 | - </ul> | |
109 | - </div> | |
110 | 101 | |
111 | - <div class="col-lg-6 col-md-6 col-sm-12"> | |
112 | - <h3>{% trans "Community inside participations" %}</h3> | |
113 | - <ul class="message-list"> | |
114 | - {% for result in results %} | |
115 | - {% include "message-preview.html" %} | |
116 | - {% empty %} | |
117 | - <li>{% trans "No contributions of this user so far." %}</li> | |
118 | - {% endfor %} | |
119 | - </ul> | |
102 | + {% if user_.badge_set.exists %} | |
103 | + <div class="col-lg-8 col-md-12 col-sm-7"> | |
104 | + <div class="panel panel-default"> | |
105 | + <div class="panel-heading"> | |
106 | + <h3 class="panel-title">{% trans "Badges" %}</h3> | |
107 | + </div> | |
108 | + <div class="panel-body"> | |
109 | + <div> | |
110 | + {% for badge in user_.badge_set.all %} | |
111 | + {% translate badge as badge_trans %} | |
112 | + <img src="{{ badge.get_badge_url }}" title="({{ badge_trans.title }}) {{ badge_trans.description }}" /> | |
113 | + {% endfor %} | |
114 | + </div> | |
115 | + </div> | |
116 | + </div> | |
120 | 117 | </div> |
118 | + {% endif %} | |
119 | + | |
120 | + </div> <!-- End of user-profile row --> | |
121 | + | |
122 | + <div class="row"> | |
123 | + | |
124 | + <div class="col-lg-6 col-md-6 col-sm-12"> | |
125 | + <h3>{% trans "Latest posted" %} </h3> | |
126 | + <ul class="message-list"> | |
127 | + {% for doc in emails %} | |
128 | + {% include "message-preview.html" with result=doc %} | |
129 | + {% empty %} | |
130 | + <li>{% trans "There are no posts by this user so far." %}</li> | |
131 | + {% endfor %} | |
132 | + </ul> | |
133 | + </div> | |
134 | + | |
135 | + <div class="col-lg-6 col-md-6 col-sm-12"> | |
136 | + <h3>{% trans "Community inside participations" %}</h3> | |
137 | + <ul class="message-list"> | |
138 | + {% for result in results %} | |
139 | + {% include "message-preview.html" %} | |
140 | + {% empty %} | |
141 | + <li>{% trans "No contributions of this user so far." %}</li> | |
142 | + {% endfor %} | |
143 | + </ul> | |
144 | + </div> | |
121 | 145 | |
122 | 146 | </div> |
123 | 147 | ... | ... |
src/badger/admin.py
1 | +# -*- coding: utf-8 -*- | |
2 | + | |
1 | 3 | from django.contrib import admin |
4 | +from django.utils.translation import ugettext_lazy as _ | |
5 | + | |
6 | +from .models import Badge, BadgeI18N | |
7 | + | |
2 | 8 | |
3 | -from .models import Badge | |
9 | +class BadgeI18NInline(admin.TabularInline): | |
10 | + model = BadgeI18N | |
4 | 11 | |
5 | 12 | |
6 | 13 | class BadgeAdmin(admin.ModelAdmin): |
7 | - pass | |
14 | + inlines = [BadgeI18NInline, ] | |
15 | + list_display = ['title', 'description', 'order'] | |
16 | + list_editable = ['order', ] | |
8 | 17 | |
9 | 18 | |
10 | 19 | admin.site.register(Badge, BadgeAdmin) | ... | ... |
... | ... | @@ -0,0 +1,44 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | + | |
3 | +from django.core.management.base import BaseCommand, CommandError | |
4 | +from haystack.query import SearchQuerySet | |
5 | + | |
6 | +from accounts.models import User | |
7 | +from badger.models import Badge | |
8 | + | |
9 | + | |
10 | +class Command(BaseCommand): | |
11 | + help = "Rebuild the user's badges." | |
12 | + | |
13 | + def handle(self, *args, **kwargs): | |
14 | + for badge in Badge.objects.filter(type='auto'): | |
15 | + if not badge.comparison: | |
16 | + continue | |
17 | + elif badge.comparison == 'biggest': | |
18 | + order = u'-{}'.format(Badge.USER_ATTR_OPTS[badge.user_attr]) | |
19 | + sqs = SearchQuerySet().filter(type='user') | |
20 | + user = sqs.order_by(order)[0] | |
21 | + badge.awardees.remove(*list(badge.awardees.all())) | |
22 | + badge.awardees.add(User.objects.get(pk=user.pk)) | |
23 | + continue | |
24 | + | |
25 | + comparison = u'__{}'.format(badge.comparison) if badge.comparison \ | |
26 | + is not 'equal' else u'' | |
27 | + | |
28 | + key = u'{}{}'.format( | |
29 | + Badge.USER_ATTR_OPTS[badge.user_attr], | |
30 | + comparison | |
31 | + ) | |
32 | + opts = {key: badge.value} | |
33 | + | |
34 | + sqs = SearchQuerySet().filter( | |
35 | + type='user', | |
36 | + **opts | |
37 | + ) | |
38 | + | |
39 | + # Remove all awardees to make sure that all of then | |
40 | + # still accomplish the necessary to keep the badge | |
41 | + badge.awardees.remove(*list(badge.awardees.all())) | |
42 | + | |
43 | + for user in sqs: | |
44 | + badge.awardees.add(User.objects.get(pk=user.pk)) | ... | ... |
src/badger/management/commands/update_badges.py
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | |
3 | 3 | from django.core.management.base import BaseCommand, CommandError |
4 | +from haystack.query import SearchQuerySet | |
4 | 5 | |
5 | 6 | from accounts.models import User |
6 | -from badger.utils import get_counters_to_badge | |
7 | 7 | from badger.models import Badge |
8 | 8 | |
9 | 9 | |
... | ... | @@ -14,17 +14,26 @@ class Command(BaseCommand): |
14 | 14 | for badge in Badge.objects.filter(type='auto'): |
15 | 15 | if not badge.comparison: |
16 | 16 | continue |
17 | - for user in User.objects.all(): | |
18 | - user_counters = get_counters_to_badge(user) | |
19 | - | |
20 | - # TODO remove user if it doesn't sastify the conditions of the | |
21 | - # badge anymore | |
22 | - if badge.comparison == 'gte': | |
23 | - if user_counters[badge.user_attr] >= badge.value: | |
24 | - badge.awardees.add(user) | |
25 | - elif badge.comparison == 'lte': | |
26 | - if user_counters[badge.user_attr] <= badge.value: | |
27 | - badge.awardees.add(user) | |
28 | - elif badge.comparison == 'equal': | |
29 | - if user_counters[badge.user_attr] == badge.value: | |
30 | - badge.awardees.add(user) | |
17 | + elif badge.comparison == 'biggest': | |
18 | + order = u'-{}'.format(Badge.USER_ATTR_OPTS[badge.user_attr]) | |
19 | + sqs = SearchQuerySet().filter(type='user') | |
20 | + user = sqs.order_by(order)[0] | |
21 | + badge.awardees.add(User.objects.get(pk=user.pk)) | |
22 | + continue | |
23 | + | |
24 | + comparison = u'__{}'.format(badge.comparison) if badge.comparison \ | |
25 | + is not 'equal' else u'' | |
26 | + | |
27 | + key = u'{}{}'.format( | |
28 | + Badge.USER_ATTR_OPTS[badge.user_attr], | |
29 | + comparison | |
30 | + ) | |
31 | + opts = {key: badge.value} | |
32 | + | |
33 | + sqs = SearchQuerySet().filter( | |
34 | + type='user', | |
35 | + **opts | |
36 | + ) | |
37 | + | |
38 | + for user in sqs: | |
39 | + badge.awardees.add(User.objects.get(pk=user.pk)) | ... | ... |
src/badger/migrations/0002_auto__add_field_badge_title_en__add_field_badge_title_es__add_field_ba.py
0 → 100644
... | ... | @@ -0,0 +1,120 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | +import datetime | |
3 | +from south.db import db | |
4 | +from south.v2 import SchemaMigration | |
5 | +from django.db import models | |
6 | + | |
7 | + | |
8 | +class Migration(SchemaMigration): | |
9 | + | |
10 | + def forwards(self, orm): | |
11 | + # Adding field 'Badge.title_en' | |
12 | + db.add_column(u'badger_badge', 'title_en', | |
13 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
14 | + keep_default=False) | |
15 | + | |
16 | + # Adding field 'Badge.title_es' | |
17 | + db.add_column(u'badger_badge', 'title_es', | |
18 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
19 | + keep_default=False) | |
20 | + | |
21 | + # Adding field 'Badge.description_en' | |
22 | + db.add_column(u'badger_badge', 'description_en', | |
23 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
24 | + keep_default=False) | |
25 | + | |
26 | + # Adding field 'Badge.description_es' | |
27 | + db.add_column(u'badger_badge', 'description_es', | |
28 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
29 | + keep_default=False) | |
30 | + | |
31 | + | |
32 | + # Changing field 'Badge.description' | |
33 | + db.alter_column(u'badger_badge', 'description', self.gf('django.db.models.fields.CharField')(max_length=200, null=True)) | |
34 | + | |
35 | + # Changing field 'Badge.title' | |
36 | + db.alter_column(u'badger_badge', 'title', self.gf('django.db.models.fields.CharField')(max_length=200, null=True)) | |
37 | + | |
38 | + def backwards(self, orm): | |
39 | + # Deleting field 'Badge.title_en' | |
40 | + db.delete_column(u'badger_badge', 'title_en') | |
41 | + | |
42 | + # Deleting field 'Badge.title_es' | |
43 | + db.delete_column(u'badger_badge', 'title_es') | |
44 | + | |
45 | + # Deleting field 'Badge.description_en' | |
46 | + db.delete_column(u'badger_badge', 'description_en') | |
47 | + | |
48 | + # Deleting field 'Badge.description_es' | |
49 | + db.delete_column(u'badger_badge', 'description_es') | |
50 | + | |
51 | + | |
52 | + # Changing field 'Badge.description' | |
53 | + db.alter_column(u'badger_badge', 'description', self.gf('django.db.models.fields.CharField')(default='', max_length=200)) | |
54 | + | |
55 | + # Changing field 'Badge.title' | |
56 | + db.alter_column(u'badger_badge', 'title', self.gf('django.db.models.fields.CharField')(default='', max_length=200)) | |
57 | + | |
58 | + models = { | |
59 | + u'accounts.user': { | |
60 | + 'Meta': {'object_name': 'User'}, | |
61 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
62 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | |
63 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
64 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
65 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | |
66 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | |
67 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
68 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
69 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
70 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
71 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
72 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
73 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
74 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | |
75 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
76 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
77 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | |
78 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | |
79 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | |
80 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | |
81 | + }, | |
82 | + u'auth.group': { | |
83 | + 'Meta': {'object_name': 'Group'}, | |
84 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
85 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | |
86 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | |
87 | + }, | |
88 | + u'auth.permission': { | |
89 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | |
90 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
91 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | |
92 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
93 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
94 | + }, | |
95 | + u'badger.badge': { | |
96 | + 'Meta': {'object_name': 'Badge'}, | |
97 | + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}), | |
98 | + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), | |
99 | + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
100 | + 'description_en': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
101 | + 'description_es': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
102 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
103 | + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), | |
104 | + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
105 | + 'title_en': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
106 | + 'title_es': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
107 | + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}), | |
108 | + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | |
109 | + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}) | |
110 | + }, | |
111 | + u'contenttypes.contenttype': { | |
112 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | |
113 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
114 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
115 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
116 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | |
117 | + } | |
118 | + } | |
119 | + | |
120 | + complete_apps = ['badger'] | |
0 | 121 | \ No newline at end of file | ... | ... |
src/badger/migrations/0003_auto__add_badgei18n__add_unique_badgei18n_i18n_source_i18n_language__d.py
0 → 100644
... | ... | @@ -0,0 +1,131 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | +import datetime | |
3 | +from south.db import db | |
4 | +from south.v2 import SchemaMigration | |
5 | +from django.db import models | |
6 | + | |
7 | + | |
8 | +class Migration(SchemaMigration): | |
9 | + | |
10 | + def forwards(self, orm): | |
11 | + # Adding model 'BadgeI18N' | |
12 | + db.create_table(u'badger_badgei18n', ( | |
13 | + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | |
14 | + ('i18n_language', self.gf('django.db.models.fields.CharField')(max_length=10)), | |
15 | + ('title', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)), | |
16 | + ('description', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)), | |
17 | + ('i18n_source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', to=orm['badger.Badge'])), | |
18 | + )) | |
19 | + db.send_create_signal(u'badger', ['BadgeI18N']) | |
20 | + | |
21 | + # Adding unique constraint on 'BadgeI18N', fields ['i18n_source', 'i18n_language'] | |
22 | + db.create_unique(u'badger_badgei18n', ['i18n_source_id', 'i18n_language']) | |
23 | + | |
24 | + # Deleting field 'Badge.title_en' | |
25 | + db.delete_column(u'badger_badge', 'title_en') | |
26 | + | |
27 | + # Deleting field 'Badge.description_en' | |
28 | + db.delete_column(u'badger_badge', 'description_en') | |
29 | + | |
30 | + # Deleting field 'Badge.title_es' | |
31 | + db.delete_column(u'badger_badge', 'title_es') | |
32 | + | |
33 | + # Deleting field 'Badge.description_es' | |
34 | + db.delete_column(u'badger_badge', 'description_es') | |
35 | + | |
36 | + | |
37 | + def backwards(self, orm): | |
38 | + # Removing unique constraint on 'BadgeI18N', fields ['i18n_source', 'i18n_language'] | |
39 | + db.delete_unique(u'badger_badgei18n', ['i18n_source_id', 'i18n_language']) | |
40 | + | |
41 | + # Deleting model 'BadgeI18N' | |
42 | + db.delete_table(u'badger_badgei18n') | |
43 | + | |
44 | + # Adding field 'Badge.title_en' | |
45 | + db.add_column(u'badger_badge', 'title_en', | |
46 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
47 | + keep_default=False) | |
48 | + | |
49 | + # Adding field 'Badge.description_en' | |
50 | + db.add_column(u'badger_badge', 'description_en', | |
51 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
52 | + keep_default=False) | |
53 | + | |
54 | + # Adding field 'Badge.title_es' | |
55 | + db.add_column(u'badger_badge', 'title_es', | |
56 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
57 | + keep_default=False) | |
58 | + | |
59 | + # Adding field 'Badge.description_es' | |
60 | + db.add_column(u'badger_badge', 'description_es', | |
61 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | |
62 | + keep_default=False) | |
63 | + | |
64 | + | |
65 | + models = { | |
66 | + u'accounts.user': { | |
67 | + 'Meta': {'object_name': 'User'}, | |
68 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
69 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | |
70 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
71 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
72 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | |
73 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | |
74 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
75 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
76 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
77 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
78 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
79 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
80 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
81 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | |
82 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
83 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
84 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | |
85 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | |
86 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | |
87 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | |
88 | + }, | |
89 | + u'auth.group': { | |
90 | + 'Meta': {'object_name': 'Group'}, | |
91 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
92 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | |
93 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | |
94 | + }, | |
95 | + u'auth.permission': { | |
96 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | |
97 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
98 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | |
99 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
100 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
101 | + }, | |
102 | + u'badger.badge': { | |
103 | + 'Meta': {'object_name': 'Badge'}, | |
104 | + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}), | |
105 | + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), | |
106 | + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
107 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
108 | + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), | |
109 | + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
110 | + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}), | |
111 | + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | |
112 | + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}) | |
113 | + }, | |
114 | + u'badger.badgei18n': { | |
115 | + 'Meta': {'unique_together': "(('i18n_source', 'i18n_language'),)", 'object_name': 'BadgeI18N'}, | |
116 | + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
117 | + 'i18n_language': ('django.db.models.fields.CharField', [], {'max_length': '10'}), | |
118 | + 'i18n_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': u"orm['badger.Badge']"}), | |
119 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
120 | + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) | |
121 | + }, | |
122 | + u'contenttypes.contenttype': { | |
123 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | |
124 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
125 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
126 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
127 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | |
128 | + } | |
129 | + } | |
130 | + | |
131 | + complete_apps = ['badger'] | |
0 | 132 | \ No newline at end of file | ... | ... |
src/badger/migrations/0004_auto__add_field_badge_order.py
0 → 100644
... | ... | @@ -0,0 +1,89 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | +import datetime | |
3 | +from south.db import db | |
4 | +from south.v2 import SchemaMigration | |
5 | +from django.db import models | |
6 | + | |
7 | + | |
8 | +class Migration(SchemaMigration): | |
9 | + | |
10 | + def forwards(self, orm): | |
11 | + # Adding field 'Badge.order' | |
12 | + db.add_column(u'badger_badge', 'order', | |
13 | + self.gf('django.db.models.fields.PositiveSmallIntegerField')(default=100), | |
14 | + keep_default=False) | |
15 | + | |
16 | + | |
17 | + def backwards(self, orm): | |
18 | + # Deleting field 'Badge.order' | |
19 | + db.delete_column(u'badger_badge', 'order') | |
20 | + | |
21 | + | |
22 | + models = { | |
23 | + u'accounts.user': { | |
24 | + 'Meta': {'object_name': 'User'}, | |
25 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
26 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | |
27 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
28 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
29 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | |
30 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | |
31 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
32 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
33 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
34 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
35 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
36 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | |
37 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | |
38 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | |
39 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
40 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | |
41 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | |
42 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | |
43 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | |
44 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | |
45 | + }, | |
46 | + u'auth.group': { | |
47 | + 'Meta': {'object_name': 'Group'}, | |
48 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
49 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | |
50 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | |
51 | + }, | |
52 | + u'auth.permission': { | |
53 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | |
54 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
55 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | |
56 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
57 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
58 | + }, | |
59 | + u'badger.badge': { | |
60 | + 'Meta': {'ordering': "['order']", 'object_name': 'Badge'}, | |
61 | + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}), | |
62 | + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), | |
63 | + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
64 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
65 | + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), | |
66 | + 'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}), | |
67 | + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
68 | + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}), | |
69 | + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | |
70 | + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}) | |
71 | + }, | |
72 | + u'badger.badgei18n': { | |
73 | + 'Meta': {'unique_together': "(('i18n_source', 'i18n_language'),)", 'object_name': 'BadgeI18N'}, | |
74 | + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | |
75 | + 'i18n_language': ('django.db.models.fields.CharField', [], {'max_length': '10'}), | |
76 | + 'i18n_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': u"orm['badger.Badge']"}), | |
77 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
78 | + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) | |
79 | + }, | |
80 | + u'contenttypes.contenttype': { | |
81 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | |
82 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
83 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
84 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
85 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + complete_apps = ['badger'] | |
0 | 90 | \ No newline at end of file | ... | ... |
src/badger/models.py
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | |
3 | +from django.conf import settings | |
3 | 4 | from django.contrib.auth import get_user_model |
4 | 5 | from django.db import models |
5 | -from django.utils.translation import ugettext as _ | |
6 | +from django.utils.translation import ugettext_lazy as _ | |
7 | +from PIL import Image | |
8 | +from i18n_model.models import I18nModel | |
6 | 9 | |
7 | 10 | |
8 | 11 | class Badge(models.Model): |
... | ... | @@ -10,6 +13,7 @@ class Badge(models.Model): |
10 | 13 | (u'gte', _(u'Greater than or equal')), |
11 | 14 | (u'lte', _(u'less than or equal')), |
12 | 15 | (u'equal', _(u'Equal')), |
16 | + (u'biggest', _(u'Biggest')), | |
13 | 17 | ) |
14 | 18 | TYPE_CHOICES = ( |
15 | 19 | (u'auto', _(u'Automatically')), |
... | ... | @@ -22,8 +26,18 @@ class Badge(models.Model): |
22 | 26 | (u'revisions', _(u'Revisions')), |
23 | 27 | (u'tickets', _(u'Ticket')), |
24 | 28 | ) |
25 | - title = models.CharField(_(u'Title'), max_length=200) | |
26 | - description = models.CharField(_(u'Description'), max_length=200) | |
29 | + USER_ATTR_OPTS = { | |
30 | + u'messages': u'message_count', | |
31 | + u'revisions': u'changeset_count', | |
32 | + u'tickets': u'ticket_count', | |
33 | + u'wikis': u'wiki_count', | |
34 | + u'contributions': u'contribution_count', | |
35 | + } | |
36 | + | |
37 | + title = models.CharField(_(u'Title'), max_length=200, blank=True, | |
38 | + null=True) | |
39 | + description = models.CharField(_(u'Description'), max_length=200, | |
40 | + blank=True, null=True) | |
27 | 41 | image = models.ImageField(upload_to='badges') |
28 | 42 | type = models.CharField(_(u'Type'), max_length=200, choices=TYPE_CHOICES) |
29 | 43 | user_attr = models.CharField( |
... | ... | @@ -50,10 +64,22 @@ class Badge(models.Model): |
50 | 64 | blank=True, |
51 | 65 | null=True |
52 | 66 | ) |
67 | + order = models.PositiveSmallIntegerField(_(u'Order'), default=100) | |
53 | 68 | |
54 | 69 | class Meta: |
55 | 70 | verbose_name = _(u'Badge') |
56 | 71 | verbose_name_plural = _(u'Badges') |
72 | + ordering = ['order', ] | |
73 | + | |
74 | + def get_badge_url(self): | |
75 | + return u'{}{}'.format(settings.MEDIA_URL, self.image) | |
76 | + | |
77 | + def save(self, *args, **kwargs): | |
78 | + img = Image.open(self.image) | |
79 | + (width, height) = img.size | |
80 | + img = img.resize((50, 50), Image.ANTIALIAS) | |
81 | + super(Badge, self).save(*args, **kwargs) | |
82 | + img.save(self.image.path) | |
57 | 83 | |
58 | 84 | def __unicode__(self): |
59 | 85 | return u'{} ({}, {})'.format( |
... | ... | @@ -61,3 +87,9 @@ class Badge(models.Model): |
61 | 87 | self.get_user_attr_display(), |
62 | 88 | self.get_type_display(), |
63 | 89 | ) |
90 | + | |
91 | + | |
92 | +class BadgeI18N(I18nModel): | |
93 | + class Meta: | |
94 | + source_model = Badge | |
95 | + translation_fields = ('title', 'description') | ... | ... |
src/badger/utils.py
... | ... | @@ -2,32 +2,45 @@ |
2 | 2 | |
3 | 3 | from django.db.models import Count |
4 | 4 | |
5 | -from haystack.query import SearchQuerySet | |
6 | - | |
7 | 5 | from proxy.models import Revision, Ticket, Wiki |
8 | -from super_archives.models import Message | |
9 | - | |
10 | - | |
11 | -def get_counters_to_badge(user): | |
12 | - # count_revisions = Revision.objects.filter(author=user.username).count() | |
13 | - # count_tickets = Ticket.objects.filter(author=user.username).count() | |
14 | - # count_wikis = Wiki.objects.filter(author=user.username).count() | |
15 | - count_revisions = SearchQuerySet().filter( | |
16 | - type='changeset', | |
17 | - author=user.username | |
18 | - ).count() | |
19 | - count_tickets = SearchQuerySet().filter( | |
20 | - type='ticket', | |
21 | - author=user.username | |
22 | - ).count() | |
23 | - count_wikis = SearchQuerySet().filter( | |
24 | - type='wiki', | |
25 | - author=user.username | |
26 | - ).count() | |
27 | - return dict( | |
28 | - messages=user.emails.aggregate(Count('message'))['message__count'], | |
29 | - revisions=count_revisions, | |
30 | - tickets=count_tickets, | |
31 | - wikis=count_wikis, | |
32 | - contributions=count_revisions + count_tickets + count_wikis, | |
33 | - ) | |
6 | +from accounts.models import User | |
7 | + | |
8 | + | |
9 | +def get_wiki_counters(): | |
10 | + return { | |
11 | + author: count for author, count in Wiki.objects.values_list( | |
12 | + 'author' | |
13 | + ).annotate(count=Count('author')) | |
14 | + } | |
15 | + | |
16 | + | |
17 | +def get_revision_counters(): | |
18 | + return { | |
19 | + author: count for author, count in Revision.objects.values_list( | |
20 | + 'author' | |
21 | + ).annotate(count=Count('author')) | |
22 | + } | |
23 | + | |
24 | + | |
25 | +def get_ticket_counters(): | |
26 | + return { | |
27 | + author: count for author, count in Ticket.objects.values_list( | |
28 | + 'author' | |
29 | + ).annotate(count=Count('author')) | |
30 | + } | |
31 | + | |
32 | + | |
33 | +def get_users_counters(): | |
34 | + wiki_counters = get_wiki_counters() | |
35 | + revision_counters = get_revision_counters() | |
36 | + ticket_counters = get_ticket_counters() | |
37 | + | |
38 | + users_counters = {} | |
39 | + for user in User.objects.annotate(message_count=Count('emails__message')): | |
40 | + users_counters[user.username] = { | |
41 | + 'messages': user.message_count, | |
42 | + 'wikis': wiki_counters.get(user.username, 0), | |
43 | + 'revisions': revision_counters.get(user.username, 0), | |
44 | + 'tickets': ticket_counters.get(user.username, 0), | |
45 | + } | |
46 | + return users_counters | ... | ... |
src/colab/custom_settings.py
... | ... | @@ -9,8 +9,8 @@ TIME_ZONE = 'America/Sao_Paulo' |
9 | 9 | gettext = lambda s: s |
10 | 10 | LANGUAGES = ( |
11 | 11 | ('en', gettext('English')), |
12 | - ('es', gettext('Spanish')), | |
13 | 12 | ('pt-br', gettext('Portuguese')), |
13 | + ('es', gettext('Spanish')), | |
14 | 14 | ) |
15 | 15 | |
16 | 16 | DJANGO_DATE_FORMAT_TO_JS = { |
... | ... | @@ -18,7 +18,7 @@ DJANGO_DATE_FORMAT_TO_JS = { |
18 | 18 | 'es': ('es', 'dd/MM/yyyy'), |
19 | 19 | } |
20 | 20 | |
21 | -LANGUAGE_CODE = 'pt-br' | |
21 | +LANGUAGE_CODE = 'en' | |
22 | 22 | |
23 | 23 | # The absolute path to the folder containing the attachments |
24 | 24 | ATTACHMENTS_FOLDER_PATH = '/home/colab/trac/attachments/' |
... | ... | @@ -108,7 +108,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( |
108 | 108 | 'conversejs', |
109 | 109 | 'haystack', |
110 | 110 | 'hitcounter', |
111 | - 'badger', | |
111 | + 'i18n_model', | |
112 | 112 | |
113 | 113 | # Own apps |
114 | 114 | 'super_archives', |
... | ... | @@ -118,6 +118,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( |
118 | 118 | 'accounts', |
119 | 119 | 'proxy', |
120 | 120 | 'search', |
121 | + 'badger', | |
121 | 122 | |
122 | 123 | # Feedzilla and deps |
123 | 124 | 'feedzilla', |
... | ... | @@ -231,6 +232,7 @@ STATICFILES_DIRS = ( |
231 | 232 | ) |
232 | 233 | |
233 | 234 | STATIC_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static') |
235 | +MEDIA_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static', 'media') | |
234 | 236 | |
235 | 237 | TEMPLATE_DIRS = ( |
236 | 238 | os.path.join(BASE_DIR, 'templates'), | ... | ... |
src/colab/settings.py
src/colab/urls.py
1 | -from django.conf.urls import patterns, include, url | |
1 | +from django.conf.urls import patterns, include, url, static | |
2 | 2 | from django.conf import settings |
3 | 3 | from django.views.generic import TemplateView |
4 | 4 | from django.contrib import admin |
... | ... | @@ -31,3 +31,9 @@ urlpatterns = patterns('', |
31 | 31 | |
32 | 32 | url(r'^', include('proxy.urls')), |
33 | 33 | ) |
34 | + | |
35 | +if settings.DEBUG: | |
36 | + urlpatterns += static.static( | |
37 | + settings.MEDIA_URL, | |
38 | + document_root=settings.MEDIA_ROOT | |
39 | + ) | ... | ... |