Commit a0b656c8d13676451ff81a1cfd3e902c888b792e

Authored by Sergio Oliveira
2 parents 329eac3a 3c25ab49

Merge pull request #112 from TracyWebTech/store_badges

Store badges
@@ -81,7 +81,6 @@ def deploy(update=False): @@ -81,7 +81,6 @@ def deploy(update=False):
81 if update: 81 if update:
82 update_requirements() 82 update_requirements()
83 83
84 - load_badges()  
85 with cd('~/colab/src/'), prefix(WORKON_COLAB): 84 with cd('~/colab/src/'), prefix(WORKON_COLAB):
86 run('python manage.py syncdb') 85 run('python manage.py syncdb')
87 run('python manage.py migrate') 86 run('python manage.py migrate')
@@ -91,17 +90,6 @@ def deploy(update=False): @@ -91,17 +90,6 @@ def deploy(update=False):
91 sudo('supervisorctl restart all') 90 sudo('supervisorctl restart all')
92 91
93 92
94 -def load_badges(local=False):  
95 - path = '/vagrant/' if local else '~/colab/'  
96 -  
97 - run(u'mkdir -p {}www/media/badges'.format(path))  
98 -  
99 - with cd(u'{}src/'.format(path)), prefix(WORKON_COLAB):  
100 - run('cp badger/fixtures/images/*.png ../www/media/badges/')  
101 - run('python manage.py loaddata badger/fixtures/badges.json')  
102 - run('python manage.py update_badges')  
103 -  
104 -  
105 def rebuild_index(age=None, batch=None): 93 def rebuild_index(age=None, batch=None):
106 with cd('~/colab/src/'), prefix(WORKON_COLAB): 94 with cd('~/colab/src/'), prefix(WORKON_COLAB):
107 age_arg = '' 95 age_arg = ''
@@ -139,5 +127,4 @@ def runserver(update_requirements=False): @@ -139,5 +127,4 @@ def runserver(update_requirements=False):
139 127
140 run('python manage.py syncdb') 128 run('python manage.py syncdb')
141 run('python manage.py migrate') 129 run('python manage.py migrate')
142 - load_badges(local=True)  
143 run('python manage.py runserver 0.0.0.0:7000') 130 run('python manage.py runserver 0.0.0.0:7000')
src/accounts/templates/accounts/user_detail.html
@@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
109 <div> 109 <div>
110 {% for badge in user_.badge_set.all %} 110 {% for badge in user_.badge_set.all %}
111 {% translate badge as badge_trans %} 111 {% translate badge as badge_trans %}
112 - <img src="{{ badge.get_badge_url }}" title="({{ badge_trans.title }}) {{ badge_trans.description }}" /> 112 + <img src="data:image/png;base64,{{ badge.image_base64 }}" title="({{ badge_trans.title }}) {{ badge_trans.description }}" />
113 {% endfor %} 113 {% endfor %}
114 </div> 114 </div>
115 </div> 115 </div>
src/badger/admin.py
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 from django.contrib import admin 3 from django.contrib import admin
4 from django.utils.translation import ugettext_lazy as _ 4 from django.utils.translation import ugettext_lazy as _
5 5
  6 +from .forms import BadgeForm
6 from .models import Badge, BadgeI18N 7 from .models import Badge, BadgeI18N
7 8
8 9
@@ -11,6 +12,7 @@ class BadgeI18NInline(admin.TabularInline): @@ -11,6 +12,7 @@ class BadgeI18NInline(admin.TabularInline):
11 12
12 13
13 class BadgeAdmin(admin.ModelAdmin): 14 class BadgeAdmin(admin.ModelAdmin):
  15 + form = BadgeForm
14 inlines = [BadgeI18NInline, ] 16 inlines = [BadgeI18NInline, ]
15 list_display = ['title', 'description', 'order'] 17 list_display = ['title', 'description', 'order']
16 list_editable = ['order', ] 18 list_editable = ['order', ]
src/badger/fixtures/badges.json
@@ -1,502 +0,0 @@ @@ -1,502 +0,0 @@
1 -[  
2 -{  
3 - "pk": 6,  
4 - "model": "badger.badge",  
5 - "fields": {  
6 - "awardees": [],  
7 - "comparison": "gte",  
8 - "description": "More than 10000 Messages",  
9 - "title": "Diamond Messenger",  
10 - "image": "badges/diamond_messenger.png",  
11 - "value": 10000,  
12 - "user_attr": "messages",  
13 - "type": "auto",  
14 - "order": 4  
15 - }  
16 -},  
17 -{  
18 - "pk": 8,  
19 - "model": "badger.badge",  
20 - "fields": {  
21 - "awardees": [],  
22 - "comparison": "gte",  
23 - "description": "More than 100 messages",  
24 - "title": "Brass Messenger",  
25 - "image": "badges/brass_messenger.png",  
26 - "value": 100,  
27 - "user_attr": "messages",  
28 - "type": "auto",  
29 - "order": 1  
30 - }  
31 -},  
32 -{  
33 - "pk": 9,  
34 - "model": "badger.badge",  
35 - "fields": {  
36 - "awardees": [],  
37 - "comparison": "gte",  
38 - "description": "More than 500 Messages",  
39 - "title": "Silver Messenger",  
40 - "image": "badges/silver_messenger.png",  
41 - "value": 500,  
42 - "user_attr": "messages",  
43 - "type": "auto",  
44 - "order": 2  
45 - }  
46 -},  
47 -{  
48 - "pk": 10,  
49 - "model": "badger.badge",  
50 - "fields": {  
51 - "awardees": [],  
52 - "comparison": "gte",  
53 - "description": "More than 1000 Messages",  
54 - "title": "Gold Messenger",  
55 - "image": "badges/gold_messenger.png",  
56 - "value": 1000,  
57 - "user_attr": "messages",  
58 - "type": "auto",  
59 - "order": 3  
60 - }  
61 -},  
62 -{  
63 - "pk": 11,  
64 - "model": "badger.badge",  
65 - "fields": {  
66 - "awardees": [],  
67 - "comparison": "gte",  
68 - "description": "More than 10 Tickets",  
69 - "title": "Brass Tracker",  
70 - "image": "badges/brass_tracker.png",  
71 - "value": 10,  
72 - "user_attr": "tickets",  
73 - "type": "auto",  
74 - "order": 5  
75 - }  
76 -},  
77 -{  
78 - "pk": 12,  
79 - "model": "badger.badge",  
80 - "fields": {  
81 - "awardees": [],  
82 - "comparison": "gte",  
83 - "description": "More than 50 Tickets",  
84 - "title": "Silver Tracker",  
85 - "image": "badges/silver_tracker.png",  
86 - "value": 50,  
87 - "user_attr": "tickets",  
88 - "type": "auto",  
89 - "order": 6  
90 - }  
91 -},  
92 -{  
93 - "pk": 13,  
94 - "model": "badger.badge",  
95 - "fields": {  
96 - "awardees": [],  
97 - "comparison": "gte",  
98 - "description": "Mais que 100 Tickets",  
99 - "title": "Gold Tracker",  
100 - "image": "badges/gold_tracker.png",  
101 - "value": 100,  
102 - "user_attr": "tickets",  
103 - "type": "auto",  
104 - "order": 7  
105 - }  
106 -},  
107 -{  
108 - "pk": 14,  
109 - "model": "badger.badge",  
110 - "fields": {  
111 - "awardees": [],  
112 - "comparison": "gte",  
113 - "description": "Mais que 500 Tickets",  
114 - "title": "Diamond Tracker",  
115 - "image": "badges/diamond_tracker.png",  
116 - "value": 500,  
117 - "user_attr": "tickets",  
118 - "type": "auto",  
119 - "order": 8  
120 - }  
121 -},  
122 -{  
123 - "pk": 15,  
124 - "model": "badger.badge",  
125 - "fields": {  
126 - "awardees": [],  
127 - "comparison": "gte",  
128 - "description": "More than 100 Changesets",  
129 - "title": "Brass Coder",  
130 - "image": "badges/brass_coder.png",  
131 - "value": 100,  
132 - "user_attr": "revisions",  
133 - "type": "auto",  
134 - "order": 9  
135 - }  
136 -},  
137 -{  
138 - "pk": 16,  
139 - "model": "badger.badge",  
140 - "fields": {  
141 - "awardees": [],  
142 - "comparison": "gte",  
143 - "description": "More than 500 Changesets",  
144 - "title": "Silver Coder",  
145 - "image": "badges/silver_coder.png",  
146 - "value": 500,  
147 - "user_attr": "revisions",  
148 - "type": "auto",  
149 - "order": 10  
150 - }  
151 -},  
152 -{  
153 - "pk": 17,  
154 - "model": "badger.badge",  
155 - "fields": {  
156 - "awardees": [],  
157 - "comparison": "gte",  
158 - "description": "More than 1000 Changesets",  
159 - "title": "Gold Coder",  
160 - "image": "badges/gold_coder.png",  
161 - "value": 1000,  
162 - "user_attr": "revisions",  
163 - "type": "auto",  
164 - "order": 11  
165 - }  
166 -},  
167 -{  
168 - "pk": 18,  
169 - "model": "badger.badge",  
170 - "fields": {  
171 - "awardees": [],  
172 - "comparison": "gte",  
173 - "description": "More than 10000 Changesets",  
174 - "title": "Diamond Coder",  
175 - "image": "badges/diamond_coder.png",  
176 - "value": 10000,  
177 - "user_attr": "revisions",  
178 - "type": "auto",  
179 - "order": 12  
180 - }  
181 -},  
182 -{  
183 - "pk": 19,  
184 - "model": "badger.badge",  
185 - "fields": {  
186 - "awardees": [],  
187 - "comparison": "gte",  
188 - "description": "More than 10 Wikis",  
189 - "title": "Brass Writer",  
190 - "image": "badges/brass_writer.png",  
191 - "value": 10,  
192 - "user_attr": "wikis",  
193 - "type": "auto",  
194 - "order": 13  
195 - }  
196 -},  
197 -{  
198 - "pk": 20,  
199 - "model": "badger.badge",  
200 - "fields": {  
201 - "awardees": [],  
202 - "comparison": "gte",  
203 - "description": "More than 50 Wikis",  
204 - "title": "Silver Writer",  
205 - "image": "badges/silver_writer.png",  
206 - "value": 50,  
207 - "user_attr": "wikis",  
208 - "type": "auto",  
209 - "order": 14  
210 - }  
211 -},  
212 -{  
213 - "pk": 21,  
214 - "model": "badger.badge",  
215 - "fields": {  
216 - "awardees": [],  
217 - "comparison": "gte",  
218 - "description": "More than 100 Wikis",  
219 - "title": "Gold Writer",  
220 - "image": "badges/gold_writer.png",  
221 - "value": 100,  
222 - "user_attr": "wikis",  
223 - "type": "auto",  
224 - "order": 15  
225 - }  
226 -},  
227 -{  
228 - "pk": 22,  
229 - "model": "badger.badge",  
230 - "fields": {  
231 - "awardees": [],  
232 - "comparison": "gte",  
233 - "description": "More than 500 Wikis",  
234 - "title": "Diamond Writer",  
235 - "image": "badges/diamond_writer.png",  
236 - "value": 500,  
237 - "user_attr": "wikis",  
238 - "type": "auto",  
239 - "order": 16  
240 - }  
241 -},  
242 -{  
243 - "pk": 23,  
244 - "model": "badger.badge",  
245 - "fields": {  
246 - "awardees": [],  
247 - "comparison": "gte",  
248 - "description": "More than 500 Contributions",  
249 - "title": "Brass Contributor",  
250 - "image": "badges/brass_contributor.png",  
251 - "value": 500,  
252 - "user_attr": "contributions",  
253 - "type": "auto",  
254 - "order": 17  
255 - }  
256 -},  
257 -{  
258 - "pk": 24,  
259 - "model": "badger.badge",  
260 - "fields": {  
261 - "awardees": [],  
262 - "comparison": "gte",  
263 - "description": "More than 1000 Contributions",  
264 - "title": "Silver Contributor",  
265 - "image": "badges/silver_contributor.png",  
266 - "value": 1000,  
267 - "user_attr": "contributions",  
268 - "type": "auto",  
269 - "order": 18  
270 - }  
271 -},  
272 -{  
273 - "pk": 25,  
274 - "model": "badger.badge",  
275 - "fields": {  
276 - "awardees": [],  
277 - "comparison": "gte",  
278 - "description": "More than 3000 Contributions",  
279 - "title": "Gold Contributor",  
280 - "image": "badges/gold_contributor.png",  
281 - "value": 3000,  
282 - "user_attr": "contributions",  
283 - "type": "auto",  
284 - "order": 19  
285 - }  
286 -},  
287 -{  
288 - "pk": 26,  
289 - "model": "badger.badge",  
290 - "fields": {  
291 - "awardees": [],  
292 - "comparison": "gte",  
293 - "description": "More than 5000 Contributions",  
294 - "title": "Diamond Contributor",  
295 - "image": "badges/diamond_contributor.png",  
296 - "value": 5000,  
297 - "user_attr": "contributions",  
298 - "type": "auto",  
299 - "order": 20  
300 - }  
301 -},  
302 -{  
303 - "pk": 1,  
304 - "model": "badger.badgei18n",  
305 - "fields": {  
306 - "i18n_language": "pt-br",  
307 - "i18n_source": 8,  
308 - "description": "Mais que 100 Mensagens",  
309 - "title": "Mensageiro Bronze"  
310 - }  
311 -},  
312 -{  
313 - "pk": 2,  
314 - "model": "badger.badgei18n",  
315 - "fields": {  
316 - "i18n_language": "pt-br",  
317 - "i18n_source": 9,  
318 - "description": "Mais que 500 Mensagens",  
319 - "title": "Mensageiro Prata"  
320 - }  
321 -},  
322 -{  
323 - "pk": 3,  
324 - "model": "badger.badgei18n",  
325 - "fields": {  
326 - "i18n_language": "pt-br",  
327 - "i18n_source": 6,  
328 - "description": "Mais que 10000 Mensagens",  
329 - "title": "Mensageiro Diamante"  
330 - }  
331 -},  
332 -{  
333 - "pk": 4,  
334 - "model": "badger.badgei18n",  
335 - "fields": {  
336 - "i18n_language": "pt-br",  
337 - "i18n_source": 10,  
338 - "description": "Mais que 1000 Mensagens",  
339 - "title": "Mensageiro Ouro"  
340 - }  
341 -},  
342 -{  
343 - "pk": 5,  
344 - "model": "badger.badgei18n",  
345 - "fields": {  
346 - "i18n_language": "pt-br",  
347 - "i18n_source": 11,  
348 - "description": "Mais que 10 T\u00edquetes",  
349 - "title": "Rastreador Bronze"  
350 - }  
351 -},  
352 -{  
353 - "pk": 6,  
354 - "model": "badger.badgei18n",  
355 - "fields": {  
356 - "i18n_language": "pt-br",  
357 - "i18n_source": 12,  
358 - "description": "Mais que 50 T\u00edquetes",  
359 - "title": "Rastreador Prata"  
360 - }  
361 -},  
362 -{  
363 - "pk": 7,  
364 - "model": "badger.badgei18n",  
365 - "fields": {  
366 - "i18n_language": "pt-br",  
367 - "i18n_source": 13,  
368 - "description": "Mais que 100 T\u00edquetes",  
369 - "title": "Rastreador Ouro"  
370 - }  
371 -},  
372 -{  
373 - "pk": 8,  
374 - "model": "badger.badgei18n",  
375 - "fields": {  
376 - "i18n_language": "pt-br",  
377 - "i18n_source": 14,  
378 - "description": "Mais que 500 T\u00edquetes",  
379 - "title": "Rastreador Diamante"  
380 - }  
381 -},  
382 -{  
383 - "pk": 9,  
384 - "model": "badger.badgei18n",  
385 - "fields": {  
386 - "i18n_language": "pt-br",  
387 - "i18n_source": 15,  
388 - "description": "Mais que 100 Modifica\u00e7\u00f5es de c\u00f3digo",  
389 - "title": "Programador Bronze"  
390 - }  
391 -},  
392 -{  
393 - "pk": 10,  
394 - "model": "badger.badgei18n",  
395 - "fields": {  
396 - "i18n_language": "pt-br",  
397 - "i18n_source": 16,  
398 - "description": "Mais que 500 Modifica\u00e7\u00f5es de c\u00f3digo",  
399 - "title": "Programador Prata"  
400 - }  
401 -},  
402 -{  
403 - "pk": 11,  
404 - "model": "badger.badgei18n",  
405 - "fields": {  
406 - "i18n_language": "pt-br",  
407 - "i18n_source": 17,  
408 - "description": "Mais que 1000 Modifica\u00e7\u00f5es de c\u00f3digo",  
409 - "title": "Programador Ouro"  
410 - }  
411 -},  
412 -{  
413 - "pk": 12,  
414 - "model": "badger.badgei18n",  
415 - "fields": {  
416 - "i18n_language": "pt-br",  
417 - "i18n_source": 18,  
418 - "description": "Mais que 10000 Modifica\u00e7\u00f5es de c\u00f3digo",  
419 - "title": "Programador Diamante"  
420 - }  
421 -},  
422 -{  
423 - "pk": 13,  
424 - "model": "badger.badgei18n",  
425 - "fields": {  
426 - "i18n_language": "pt-br",  
427 - "i18n_source": 19,  
428 - "description": "Escreveu mais que 10 Wikis",  
429 - "title": "Escritor Bronze"  
430 - }  
431 -},  
432 -{  
433 - "pk": 14,  
434 - "model": "badger.badgei18n",  
435 - "fields": {  
436 - "i18n_language": "pt-br",  
437 - "i18n_source": 20,  
438 - "description": "Escreveu mais que 50 Wikis",  
439 - "title": "Escritor Prata"  
440 - }  
441 -},  
442 -{  
443 - "pk": 15,  
444 - "model": "badger.badgei18n",  
445 - "fields": {  
446 - "i18n_language": "pt-br",  
447 - "i18n_source": 21,  
448 - "description": "Escreveu mais que 100 Wikis",  
449 - "title": "Escritor Ouro"  
450 - }  
451 -},  
452 -{  
453 - "pk": 16,  
454 - "model": "badger.badgei18n",  
455 - "fields": {  
456 - "i18n_language": "pt-br",  
457 - "i18n_source": 22,  
458 - "description": "Escreveu mais que 500 Wikis",  
459 - "title": "Escritor Diamante"  
460 - }  
461 -},  
462 -{  
463 - "pk": 17,  
464 - "model": "badger.badgei18n",  
465 - "fields": {  
466 - "i18n_language": "pt-br",  
467 - "i18n_source": 23,  
468 - "description": "Mais que 500 Contribui\u00e7\u00f5es",  
469 - "title": "Contribuidor Bronze"  
470 - }  
471 -},  
472 -{  
473 - "pk": 18,  
474 - "model": "badger.badgei18n",  
475 - "fields": {  
476 - "i18n_language": "pt-br",  
477 - "i18n_source": 24,  
478 - "description": "Mais que 1000 Contribui\u00e7\u00f5es",  
479 - "title": "Contribuidor Prata"  
480 - }  
481 -},  
482 -{  
483 - "pk": 19,  
484 - "model": "badger.badgei18n",  
485 - "fields": {  
486 - "i18n_language": "pt-br",  
487 - "i18n_source": 25,  
488 - "description": "Mais que 3000 Contribui\u00e7\u00f5es",  
489 - "title": "Contribuidor Ouro"  
490 - }  
491 -},  
492 -{  
493 - "pk": 20,  
494 - "model": "badger.badgei18n",  
495 - "fields": {  
496 - "i18n_language": "pt-br",  
497 - "i18n_source": 26,  
498 - "description": "Mais que 5000 Contribui\u00e7\u00f5es",  
499 - "title": "Contribuidor Diamante"  
500 - }  
501 -}  
502 -]  
src/badger/fixtures/images/brass_coder.png

3.33 KB

src/badger/fixtures/images/brass_contributor.png

3.65 KB

src/badger/fixtures/images/brass_messenger.png

3.2 KB

src/badger/fixtures/images/brass_tracker.png

3.48 KB

src/badger/fixtures/images/brass_writer.png

3.51 KB

src/badger/fixtures/images/diamond_coder.png

3.04 KB

src/badger/fixtures/images/diamond_contributor.png

3.16 KB

src/badger/fixtures/images/diamond_messenger.png

2.81 KB

src/badger/fixtures/images/diamond_tracker.png

3.02 KB

src/badger/fixtures/images/diamond_writer.png

3.05 KB

src/badger/fixtures/images/gold_coder.png

2.77 KB

src/badger/fixtures/images/gold_contributor.png

2.87 KB

src/badger/fixtures/images/gold_messenger.png

2.56 KB

src/badger/fixtures/images/gold_tracker.png

2.81 KB

src/badger/fixtures/images/gold_writer.png

2.81 KB

src/badger/fixtures/images/silver_coder.png

2.75 KB

src/badger/fixtures/images/silver_contributor.png

2.71 KB

src/badger/fixtures/images/silver_messenger.png

2.47 KB

src/badger/fixtures/images/silver_tracker.png

2.62 KB

src/badger/fixtures/images/silver_writer.png

2.66 KB

src/badger/forms.py 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +import base64
  2 +import StringIO
  3 +
  4 +from django import forms
  5 +from django.utils.translation import ugettext_lazy as _
  6 +
  7 +from PIL import Image
  8 +
  9 +from .models import Badge
  10 +
  11 +
  12 +class BadgeForm(forms.ModelForm):
  13 + image = forms.ImageField(label=_(u'Image'))
  14 +
  15 + class Meta:
  16 + model = Badge
  17 + fields = (
  18 + 'title', 'description', 'image', 'user_attr', 'comparison',
  19 + 'value', 'awardees'
  20 + )
  21 +
  22 + def save(self, commit=True):
  23 +
  24 + instance = super(BadgeForm, self).save(commit=False)
  25 +
  26 + img = Image.open(self.cleaned_data['image'])
  27 + img = img.resize((50, 50), Image.ANTIALIAS)
  28 + f = StringIO.StringIO()
  29 + img.save(f, 'png')
  30 + instance.image_base64 = f.getvalue().encode('base64')
  31 + f.close()
  32 +
  33 + if commit:
  34 + instance.save()
  35 +
  36 + return instance
src/badger/migrations/0005_auto__add_field_badge_image_base64.py 0 → 100644
@@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
  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.image_base64'
  12 + db.add_column(u'badger_badge', 'image_base64',
  13 + self.gf('django.db.models.fields.TextField')(default=''),
  14 + keep_default=False)
  15 +
  16 +
  17 + def backwards(self, orm):
  18 + # Deleting field 'Badge.image_base64'
  19 + db.delete_column(u'badger_badge', 'image_base64')
  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'badger.badge': {
  61 + 'Meta': {'ordering': "['order']", 'object_name': 'Badge'},
  62 + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}),
  63 + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
  64 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  65 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  66 + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
  67 + 'image_base64': ('django.db.models.fields.TextField', [], {}),
  68 + 'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
  69 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  70 + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
  71 + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
  72 + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'})
  73 + },
  74 + u'badger.badgei18n': {
  75 + 'Meta': {'unique_together': "(('i18n_source', 'i18n_language'),)", 'object_name': 'BadgeI18N'},
  76 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  77 + 'i18n_language': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
  78 + 'i18n_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': u"orm['badger.Badge']"}),
  79 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  80 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
  81 + },
  82 + u'contenttypes.contenttype': {
  83 + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
  84 + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  85 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  86 + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  87 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
  88 + }
  89 + }
  90 +
  91 + complete_apps = ['badger']
0 \ No newline at end of file 92 \ No newline at end of file
src/badger/migrations/0006_imgpath_to_base64_field.py 0 → 100644
@@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
  1 +# -*- coding: utf-8 -*-
  2 +import base64
  3 +import os
  4 +
  5 +import datetime
  6 +from south.db import db
  7 +from south.v2 import DataMigration
  8 +from django.db import models
  9 +from django.conf import settings
  10 +
  11 +class Migration(DataMigration):
  12 +
  13 + def forwards(self, orm):
  14 + for obj in orm.Badge.objects.all():
  15 + img = open(os.path.join(settings.MEDIA_ROOT, obj.image.path))
  16 + obj.image_base64 = base64.b64encode(img.read())
  17 + obj.save()
  18 +
  19 + def backwards(self, orm):
  20 + for obj in orm.Badge.objects.all():
  21 + obj.image_base64 = ''
  22 + obj.save()
  23 +
  24 + models = {
  25 + u'accounts.user': {
  26 + 'Meta': {'object_name': 'User'},
  27 + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
  28 + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}),
  29 + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  30 + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
  31 + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
  32 + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
  33 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  34 + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  35 + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
  36 + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
  37 + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
  38 + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
  39 + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
  40 + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
  41 + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
  42 + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  43 + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  44 + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
  45 + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
  46 + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
  47 + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
  48 + },
  49 + u'auth.group': {
  50 + 'Meta': {'object_name': 'Group'},
  51 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  52 + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
  53 + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
  54 + },
  55 + u'auth.permission': {
  56 + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
  57 + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  58 + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
  59 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  60 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
  61 + },
  62 + u'badger.badge': {
  63 + 'Meta': {'ordering': "['order']", 'object_name': 'Badge'},
  64 + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}),
  65 + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
  66 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  67 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  68 + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
  69 + 'image_base64': ('django.db.models.fields.TextField', [], {}),
  70 + 'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
  71 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  72 + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
  73 + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
  74 + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'})
  75 + },
  76 + u'badger.badgei18n': {
  77 + 'Meta': {'unique_together': "(('i18n_source', 'i18n_language'),)", 'object_name': 'BadgeI18N'},
  78 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  79 + 'i18n_language': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
  80 + 'i18n_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': u"orm['badger.Badge']"}),
  81 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  82 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
  83 + },
  84 + u'contenttypes.contenttype': {
  85 + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
  86 + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  87 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  88 + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  89 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
  90 + }
  91 + }
  92 +
  93 + complete_apps = ['badger']
  94 + symmetrical = True
src/badger/migrations/0007_auto__del_field_badge_image.py 0 → 100644
@@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
  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 + # Deleting field 'Badge.image'
  12 + db.delete_column(u'badger_badge', 'image')
  13 +
  14 +
  15 + def backwards(self, orm):
  16 + # Adding field 'Badge.image'
  17 + db.add_column(u'badger_badge', 'image',
  18 + self.gf('django.db.models.fields.files.ImageField')(default='', max_length=100),
  19 + keep_default=False)
  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'badger.badge': {
  61 + 'Meta': {'ordering': "['order']", 'object_name': 'Badge'},
  62 + 'awardees': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['accounts.User']", 'null': 'True', 'blank': 'True'}),
  63 + 'comparison': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
  64 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  65 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  66 + 'image_base64': ('django.db.models.fields.TextField', [], {}),
  67 + 'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
  68 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  69 + 'type': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
  70 + 'user_attr': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
  71 + 'value': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'})
  72 + },
  73 + u'badger.badgei18n': {
  74 + 'Meta': {'unique_together': "(('i18n_source', 'i18n_language'),)", 'object_name': 'BadgeI18N'},
  75 + 'description': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
  76 + 'i18n_language': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
  77 + 'i18n_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': u"orm['badger.Badge']"}),
  78 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  79 + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
  80 + },
  81 + u'contenttypes.contenttype': {
  82 + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
  83 + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  84 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  85 + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  86 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
  87 + }
  88 + }
  89 +
  90 + complete_apps = ['badger']
0 \ No newline at end of file 91 \ No newline at end of file
src/badger/models.py
@@ -4,7 +4,6 @@ from django.conf import settings @@ -4,7 +4,6 @@ from django.conf import settings
4 from django.contrib.auth import get_user_model 4 from django.contrib.auth import get_user_model
5 from django.db import models 5 from django.db import models
6 from django.utils.translation import ugettext_lazy as _ 6 from django.utils.translation import ugettext_lazy as _
7 -from PIL import Image  
8 from i18n_model.models import I18nModel 7 from i18n_model.models import I18nModel
9 8
10 9
@@ -38,7 +37,7 @@ class Badge(models.Model): @@ -38,7 +37,7 @@ class Badge(models.Model):
38 null=True) 37 null=True)
39 description = models.CharField(_(u'Description'), max_length=200, 38 description = models.CharField(_(u'Description'), max_length=200,
40 blank=True, null=True) 39 blank=True, null=True)
41 - image = models.ImageField(upload_to='badges') 40 + image_base64 = models.TextField(_(u'Image'))
42 type = models.CharField(_(u'Type'), max_length=200, choices=TYPE_CHOICES) 41 type = models.CharField(_(u'Type'), max_length=200, choices=TYPE_CHOICES)
43 user_attr = models.CharField( 42 user_attr = models.CharField(
44 _(u'User attribute'),max_length=100, 43 _(u'User attribute'),max_length=100,
@@ -71,16 +70,6 @@ class Badge(models.Model): @@ -71,16 +70,6 @@ class Badge(models.Model):
71 verbose_name_plural = _(u'Badges') 70 verbose_name_plural = _(u'Badges')
72 ordering = ['order', ] 71 ordering = ['order', ]
73 72
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)  
83 -  
84 def __unicode__(self): 73 def __unicode__(self):
85 return u'{} ({}, {})'.format( 74 return u'{} ({}, {})'.format(
86 self.title, 75 self.title,