Commit ee69bd3a7f847b2f882d36b88d2a467e4a97116e

Authored by Sergio Oliveira
2 parents 10be474a 16769435

Merge branch 'master' of github.com:TracyWebTech/colab

@@ -47,6 +47,7 @@ Interface @@ -47,6 +47,7 @@ Interface
47 * Paginar discussoes 47 * Paginar discussoes
48 * Paginar dashboard de discussoes 48 * Paginar dashboard de discussoes
49 * Highlight mostrar resultados normalizados (com e sem acentos) 49 * Highlight mostrar resultados normalizados (com e sem acentos)
  50 +* Adicionar opção para escolha de idioma
50 51
51 52
52 Outros 53 Outros
requirements.txt
@@ -16,6 +16,7 @@ django-taggit @@ -16,6 +16,7 @@ django-taggit
16 python-memcached 16 python-memcached
17 django-hitcounter 17 django-hitcounter
18 Pillow 18 Pillow
  19 +django-i18n-model
19 20
20 gunicorn 21 gunicorn
21 gevent 22 gevent
src/accounts/migrations/0006_auto__add_field_user_modified.py 0 → 100644
@@ -0,0 +1,69 @@ @@ -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,6 +16,7 @@ class User(AbstractUser):
16 google_talk = models.EmailField(null=True, blank=True) 16 google_talk = models.EmailField(null=True, blank=True)
17 webpage = models.CharField(max_length=256, null=True, blank=True) 17 webpage = models.CharField(max_length=256, null=True, blank=True)
18 verification_hash = models.CharField(max_length=32, null=True, blank=True) 18 verification_hash = models.CharField(max_length=32, null=True, blank=True)
  19 + modified = models.DateTimeField(auto_now=True)
19 20
20 def get_absolute_url(self): 21 def get_absolute_url(self):
21 return reverse('user_profile', kwargs={'username': self.username}) 22 return reverse('user_profile', kwargs={'username': self.username})
src/accounts/search_indexes.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
3 from haystack import indexes 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 from .models import User 8 from .models import User
6 9
7 10
8 class UserIndex(indexes.SearchIndex, indexes.Indexable): 11 class UserIndex(indexes.SearchIndex, indexes.Indexable):
9 # common fields 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 title = indexes.CharField(model_attr='get_full_name') 15 title = indexes.CharField(model_attr='get_full_name')
13 description = indexes.CharField(null=True) 16 description = indexes.CharField(null=True)
14 type = indexes.CharField() 17 type = indexes.CharField()
15 icon_name = indexes.CharField() 18 icon_name = indexes.CharField()
16 19
17 # extra fields 20 # extra fields
18 - username = indexes.CharField(model_attr='username') 21 + username = indexes.CharField(model_attr='username', stored=False)
19 name = indexes.CharField(model_attr='get_full_name') 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 institution = indexes.CharField(model_attr='institution', null=True) 24 institution = indexes.CharField(model_attr='institution', null=True)
22 role = indexes.CharField(model_attr='role', null=True) 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 def get_model(self): 35 def get_model(self):
27 return User 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 def get_updated_field(self): 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 def prepare_description(self, obj): 59 def prepare_description(self, obj):
33 return u'{}\n{}\n{}\n{}'.format( 60 return u'{}\n{}\n{}\n{}'.format(
@@ -40,5 +67,17 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable): @@ -40,5 +67,17 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable):
40 def prepare_type(self, obj): 67 def prepare_type(self, obj):
41 return u'user' 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 def index_queryset(self, using=None): 82 def index_queryset(self, using=None):
44 return self.get_model().objects.filter(is_active=True) 83 return self.get_model().objects.filter(is_active=True)
src/accounts/templates/accounts/user_detail.html
1 {% extends "base.html" %} 1 {% extends "base.html" %}
2 -{% load i18n gravatar %} 2 +
  3 +{% load i18n gravatar i18n_model %}
  4 +
3 5
4 {% block head_js %} 6 {% block head_js %}
5 {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=300 %} 7 {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=300 %}
@@ -36,40 +38,41 @@ @@ -36,40 +38,41 @@
36 38
37 <ul class="unstyled-list"> 39 <ul class="unstyled-list">
38 {% if user_.institution or user_.role %} 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 {% endif %} 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 {% endif %} 64 {% endif %}
62 - {% endif %}  
63 </ul> 65 </ul>
64 66
65 {% if user_.mailinglists %} 67 {% if user_.mailinglists %}
66 - <b>{% trans 'Subscribes: ' %}</b> 68 + <b>{% trans 'Subscribes: ' %}</b>
67 {% for list in user_.mailinglists %} 69 {% for list in user_.mailinglists %}
68 <span class="label label-primary">{{ list }}</span> 70 <span class="label label-primary">{{ list }}</span>
69 {% endfor %} 71 {% endfor %}
70 {% endif %} 72 {% endif %}
71 73
72 <div class="divider"></div> 74 <div class="divider"></div>
  75 +
73 </div> 76 </div>
74 77
75 <div class="col-lg-4 col-md-4 col-sm-7"> 78 <div class="col-lg-4 col-md-4 col-sm-7">
@@ -95,29 +98,50 @@ @@ -95,29 +98,50 @@
95 </div> 98 </div>
96 </div> 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 </div> 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 </div> 146 </div>
123 147
src/badger/admin.py
  1 +# -*- coding: utf-8 -*-
  2 +
1 from django.contrib import admin 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 class BadgeAdmin(admin.ModelAdmin): 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 admin.site.register(Badge, BadgeAdmin) 19 admin.site.register(Badge, BadgeAdmin)
src/badger/management/commands/rebuild_badges.py 0 → 100644
@@ -0,0 +1,44 @@ @@ -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 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
3 from django.core.management.base import BaseCommand, CommandError 3 from django.core.management.base import BaseCommand, CommandError
  4 +from haystack.query import SearchQuerySet
4 5
5 from accounts.models import User 6 from accounts.models import User
6 -from badger.utils import get_counters_to_badge  
7 from badger.models import Badge 7 from badger.models import Badge
8 8
9 9
@@ -14,17 +14,26 @@ class Command(BaseCommand): @@ -14,17 +14,26 @@ class Command(BaseCommand):
14 for badge in Badge.objects.filter(type='auto'): 14 for badge in Badge.objects.filter(type='auto'):
15 if not badge.comparison: 15 if not badge.comparison:
16 continue 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 @@ @@ -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 \ No newline at end of file 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 @@ @@ -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 \ No newline at end of file 132 \ No newline at end of file
src/badger/migrations/0004_auto__add_field_badge_order.py 0 → 100644
@@ -0,0 +1,89 @@ @@ -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 \ No newline at end of file 90 \ No newline at end of file
src/badger/models.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
  3 +from django.conf import settings
3 from django.contrib.auth import get_user_model 4 from django.contrib.auth import get_user_model
4 from django.db import models 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 class Badge(models.Model): 11 class Badge(models.Model):
@@ -10,6 +13,7 @@ class Badge(models.Model): @@ -10,6 +13,7 @@ class Badge(models.Model):
10 (u'gte', _(u'Greater than or equal')), 13 (u'gte', _(u'Greater than or equal')),
11 (u'lte', _(u'less than or equal')), 14 (u'lte', _(u'less than or equal')),
12 (u'equal', _(u'Equal')), 15 (u'equal', _(u'Equal')),
  16 + (u'biggest', _(u'Biggest')),
13 ) 17 )
14 TYPE_CHOICES = ( 18 TYPE_CHOICES = (
15 (u'auto', _(u'Automatically')), 19 (u'auto', _(u'Automatically')),
@@ -22,8 +26,18 @@ class Badge(models.Model): @@ -22,8 +26,18 @@ class Badge(models.Model):
22 (u'revisions', _(u'Revisions')), 26 (u'revisions', _(u'Revisions')),
23 (u'tickets', _(u'Ticket')), 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 image = models.ImageField(upload_to='badges') 41 image = models.ImageField(upload_to='badges')
28 type = models.CharField(_(u'Type'), max_length=200, choices=TYPE_CHOICES) 42 type = models.CharField(_(u'Type'), max_length=200, choices=TYPE_CHOICES)
29 user_attr = models.CharField( 43 user_attr = models.CharField(
@@ -50,10 +64,22 @@ class Badge(models.Model): @@ -50,10 +64,22 @@ class Badge(models.Model):
50 blank=True, 64 blank=True,
51 null=True 65 null=True
52 ) 66 )
  67 + order = models.PositiveSmallIntegerField(_(u'Order'), default=100)
53 68
54 class Meta: 69 class Meta:
55 verbose_name = _(u'Badge') 70 verbose_name = _(u'Badge')
56 verbose_name_plural = _(u'Badges') 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 def __unicode__(self): 84 def __unicode__(self):
59 return u'{} ({}, {})'.format( 85 return u'{} ({}, {})'.format(
@@ -61,3 +87,9 @@ class Badge(models.Model): @@ -61,3 +87,9 @@ class Badge(models.Model):
61 self.get_user_attr_display(), 87 self.get_user_attr_display(),
62 self.get_type_display(), 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,32 +2,45 @@
2 2
3 from django.db.models import Count 3 from django.db.models import Count
4 4
5 -from haystack.query import SearchQuerySet  
6 -  
7 from proxy.models import Revision, Ticket, Wiki 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 = &#39;America/Sao_Paulo&#39; @@ -9,8 +9,8 @@ TIME_ZONE = &#39;America/Sao_Paulo&#39;
9 gettext = lambda s: s 9 gettext = lambda s: s
10 LANGUAGES = ( 10 LANGUAGES = (
11 ('en', gettext('English')), 11 ('en', gettext('English')),
12 - ('es', gettext('Spanish')),  
13 ('pt-br', gettext('Portuguese')), 12 ('pt-br', gettext('Portuguese')),
  13 + ('es', gettext('Spanish')),
14 ) 14 )
15 15
16 DJANGO_DATE_FORMAT_TO_JS = { 16 DJANGO_DATE_FORMAT_TO_JS = {
@@ -18,7 +18,7 @@ DJANGO_DATE_FORMAT_TO_JS = { @@ -18,7 +18,7 @@ DJANGO_DATE_FORMAT_TO_JS = {
18 'es': ('es', 'dd/MM/yyyy'), 18 'es': ('es', 'dd/MM/yyyy'),
19 } 19 }
20 20
21 -LANGUAGE_CODE = 'pt-br' 21 +LANGUAGE_CODE = 'en'
22 22
23 # The absolute path to the folder containing the attachments 23 # The absolute path to the folder containing the attachments
24 ATTACHMENTS_FOLDER_PATH = '/home/colab/trac/attachments/' 24 ATTACHMENTS_FOLDER_PATH = '/home/colab/trac/attachments/'
@@ -108,7 +108,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( @@ -108,7 +108,7 @@ INSTALLED_APPS = INSTALLED_APPS + (
108 'conversejs', 108 'conversejs',
109 'haystack', 109 'haystack',
110 'hitcounter', 110 'hitcounter',
111 - 'badger', 111 + 'i18n_model',
112 112
113 # Own apps 113 # Own apps
114 'super_archives', 114 'super_archives',
@@ -118,6 +118,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( @@ -118,6 +118,7 @@ INSTALLED_APPS = INSTALLED_APPS + (
118 'accounts', 118 'accounts',
119 'proxy', 119 'proxy',
120 'search', 120 'search',
  121 + 'badger',
121 122
122 # Feedzilla and deps 123 # Feedzilla and deps
123 'feedzilla', 124 'feedzilla',
@@ -231,6 +232,7 @@ STATICFILES_DIRS = ( @@ -231,6 +232,7 @@ STATICFILES_DIRS = (
231 ) 232 )
232 233
233 STATIC_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static') 234 STATIC_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static')
  235 +MEDIA_ROOT = os.path.join(BASE_DIR, '..', 'www', 'static', 'media')
234 236
235 TEMPLATE_DIRS = ( 237 TEMPLATE_DIRS = (
236 os.path.join(BASE_DIR, 'templates'), 238 os.path.join(BASE_DIR, 'templates'),
src/colab/settings.py
@@ -80,5 +80,6 @@ USE_TZ = True @@ -80,5 +80,6 @@ USE_TZ = True
80 # https://docs.djangoproject.com/en/dev/howto/static-files/ 80 # https://docs.djangoproject.com/en/dev/howto/static-files/
81 81
82 STATIC_URL = '/static/' 82 STATIC_URL = '/static/'
  83 +MEDIA_URL = '/media/'
83 84
84 from custom_settings import * 85 from custom_settings import *
src/colab/urls.py
1 -from django.conf.urls import patterns, include, url 1 +from django.conf.urls import patterns, include, url, static
2 from django.conf import settings 2 from django.conf import settings
3 from django.views.generic import TemplateView 3 from django.views.generic import TemplateView
4 from django.contrib import admin 4 from django.contrib import admin
@@ -31,3 +31,9 @@ urlpatterns = patterns(&#39;&#39;, @@ -31,3 +31,9 @@ urlpatterns = patterns(&#39;&#39;,
31 31
32 url(r'^', include('proxy.urls')), 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 + )