Commit 0cb51df4b0e5373a703e896606300331cdfc4dcf
1 parent
845d8ecf
Exists in
master
and in
39 other branches
Merge com a ultima versao do bitcket: https://bitbucket.org/seocam/atu-colab/src/4ee3ca57614e
Showing
24 changed files
with
363 additions
and
71 deletions
Show diff stats
TODO.rst
@@ -9,9 +9,9 @@ TODO | @@ -9,9 +9,9 @@ TODO | ||
9 | * Yure: Adicionar data do ultimo import de emails no footer | 9 | * Yure: Adicionar data do ultimo import de emails no footer |
10 | * Yure: Detectar links no conteudo e exibi-los como tal | 10 | * Yure: Detectar links no conteudo e exibi-los como tal |
11 | * Yure: BUG: Display of HTML emails are wrong | 11 | * Yure: BUG: Display of HTML emails are wrong |
12 | -* Yure: Cadastrar usuário em lista pelo formulario de cadastro | ||
13 | * Arquivo "search.html" existente em "atu-colab/colab/templates" pode ser melhorado com relação ao conteúdo repetitivo dos "Tipos" exibidos no "Filtro" da página | 12 | * Arquivo "search.html" existente em "atu-colab/colab/templates" pode ser melhorado com relação ao conteúdo repetitivo dos "Tipos" exibidos no "Filtro" da página |
14 | -* Criar validador de urls para twitter, facebook e página pessoal do user profile | 13 | +* BUG: Criar validador de urls para twitter, facebook e página pessoal do user profile |
14 | +* Mostrar dados do twitter, facebook, gtalk e página pessoal somente para os usuários que estiverem logados | ||
15 | 15 | ||
16 | * Configurar ADMINS no arquivo settings_local.py | 16 | * Configurar ADMINS no arquivo settings_local.py |
17 | * HTTPS para o trac, subversion e colab | 17 | * HTTPS para o trac, subversion e colab |
@@ -20,11 +20,10 @@ TODO | @@ -20,11 +20,10 @@ TODO | ||
20 | * Timezones no trac/colab/solr nao estao compativeis | 20 | * Timezones no trac/colab/solr nao estao compativeis |
21 | 21 | ||
22 | * Template de login nao exibe corretamente no firefox/linux | 22 | * Template de login nao exibe corretamente no firefox/linux |
23 | -* Quando usuario se cadastra com email errado o email nunca eh validado, | ||
24 | -e o username fica preso 'pra sempre'. | 23 | +* Quando usuario se cadastra com email errado o email nunca eh validado, e o username fica preso 'pra sempre'. |
25 | * Nome dos usuarios errado nos emails que vem do Solr | 24 | * Nome dos usuarios errado nos emails que vem do Solr |
26 | * Adicionar ordering na busca | 25 | * Adicionar ordering na busca |
27 | -* Criar tipo usuario no solr | 26 | +* Criar tipo usuario no solr |
28 | * Substituir sistema de cadastro por django-registration | 27 | * Substituir sistema de cadastro por django-registration |
29 | * Utilizar pysolr para efetuar queries no Solr | 28 | * Utilizar pysolr para efetuar queries no Solr |
30 | * Melhorar buscas (case insensitive match, palavras com acentos) | 29 | * Melhorar buscas (case insensitive match, palavras com acentos) |
@@ -40,13 +39,13 @@ e o username fica preso 'pra sempre'. | @@ -40,13 +39,13 @@ e o username fica preso 'pra sempre'. | ||
40 | * Merge emails dos usuarios | 39 | * Merge emails dos usuarios |
41 | * Implementar badge system | 40 | * Implementar badge system |
42 | * Melhorar filtros | 41 | * Melhorar filtros |
43 | -* Link do thread preview deve enviar para mensagem da thread (anchor) (Útil? discutir com Jean) | 42 | +* Link do thread preview deve enviar para mensagem da thread (anchor) |
44 | * Tornar todas as strings traduziveis | 43 | * Tornar todas as strings traduziveis |
45 | * Sugestão de como a divisão do edital seria melhor | 44 | * Sugestão de como a divisão do edital seria melhor |
46 | * Indexar anexos da wiki (using Tika http://wiki.apache.org/solr/ExtractingRequestHandler) | 45 | * Indexar anexos da wiki (using Tika http://wiki.apache.org/solr/ExtractingRequestHandler) |
47 | * Filtrar usando calendario (como google analytics) | 46 | * Filtrar usando calendario (como google analytics) |
48 | * Melhorar relevancia das buscas usando dismax queryparser | 47 | * Melhorar relevancia das buscas usando dismax queryparser |
49 | -* Chat estilo Gmail | 48 | +* Chat estilo Gmail usando o mensageiro Interlegis |
50 | * Sistema de gerencia de conteúdo | 49 | * Sistema de gerencia de conteúdo |
51 | * Versao mobile | 50 | * Versao mobile |
52 | * Exibir discussões relacionadas na barra da direita das discussões | 51 | * Exibir discussões relacionadas na barra da direita das discussões |
@@ -56,9 +55,14 @@ e o username fica preso 'pra sempre'. | @@ -56,9 +55,14 @@ e o username fica preso 'pra sempre'. | ||
56 | * Contar page views no trac (ticket, wiki e changeset) e utiliza-los para rankear paginas nas buscas | 55 | * Contar page views no trac (ticket, wiki e changeset) e utiliza-los para rankear paginas nas buscas |
57 | * Mostrar highlight nas buscas | 56 | * Mostrar highlight nas buscas |
58 | * Sistema de tags para as mensagens | 57 | * Sistema de tags para as mensagens |
58 | +* Tag cloud para as mensagens, ao lado direito da thread | ||
59 | * Pagina home para cada lista com os mesmo filtros da home atual | 59 | * Pagina home para cada lista com os mesmo filtros da home atual |
60 | * Permitir que usuario entre e saia de listas ao editar perfil | 60 | * Permitir que usuario entre e saia de listas ao editar perfil |
61 | * Planet Interlegis (agregador de blogs) | 61 | * Planet Interlegis (agregador de blogs) |
62 | -* Filtros especificos para tipos diferentes na busca | 62 | +* Filtros específicos para tipos diferentes na busca da thread |
63 | +* Link para a mensagem original no histórico do Mailman (popup ajax) | ||
64 | +* Filtro de mensagens nas listas acumulativos, podendo ligar e desligar todos | ||
65 | +* Reduzir campos na tela de cadastro, transferindo-os como aba para a tela de profile, junto com a aba de listas a se inscrever) | ||
66 | + | ||
63 | * Indice criado manualmente. Automatizar: | 67 | * Indice criado manualmente. Automatizar: |
64 | * create index super_archives_message_body_idx ON super_archives_message ((substring(body,0,1024))); | 68 | * create index super_archives_message_body_idx ON super_archives_message ((substring(body,0,1024))); |
@@ -0,0 +1,74 @@ | @@ -0,0 +1,74 @@ | ||
1 | +#!/usr/bin/env python | ||
2 | +# encoding: utf-8 | ||
3 | + | ||
4 | +from django.contrib.syndication.views import Feed | ||
5 | +from django.utils.translation import ugettext as _ | ||
6 | + | ||
7 | +from colab.super_archives.models import Thread | ||
8 | +from colab.super_archives import queries | ||
9 | +from colab import solrutils | ||
10 | + | ||
11 | +class LatestThreadsFeeds(Feed): | ||
12 | + title = _(u'Últimas Discussões') | ||
13 | + link = '/rss/threads/latest/' | ||
14 | + | ||
15 | + def items(self): | ||
16 | + return queries.get_latest_threads()[:20] | ||
17 | + | ||
18 | + def item_link(self, item): | ||
19 | + return item.latest_message.url | ||
20 | + | ||
21 | + def item_title(self, item): | ||
22 | + return item.latest_message.subject_clean | ||
23 | + | ||
24 | + def item_description(self, item): | ||
25 | + return item.latest_message.body | ||
26 | + | ||
27 | + | ||
28 | +class HottestThreadsFeeds(Feed): | ||
29 | + title = _(u'Discussões Mais Relevantes') | ||
30 | + link = '/rss/threads/hottest/' | ||
31 | + | ||
32 | + def items(self): | ||
33 | + return queries.get_hottest_threads()[:20] | ||
34 | + | ||
35 | + def item_link(self, item): | ||
36 | + return item.latest_message.url | ||
37 | + | ||
38 | + def item_title(self, item): | ||
39 | + return item.latest_message.subject_clean | ||
40 | + | ||
41 | + def item_description(self, item): | ||
42 | + return item.latest_message.body | ||
43 | + | ||
44 | + | ||
45 | +class LatestColabFeeds(Feed): | ||
46 | + title = _(u'Últimas Colaborações') | ||
47 | + link = '/rss/colab/latest/' | ||
48 | + | ||
49 | + def items(self): | ||
50 | + items = solrutils.get_latest_collaborations(20) | ||
51 | + return items | ||
52 | + | ||
53 | + def item_title(self, item): | ||
54 | + type_ = item.get('Type') + ': ' | ||
55 | + mailinglist = item.get('mailinglist') | ||
56 | + | ||
57 | + if mailinglist: | ||
58 | + prefix = type_ + mailinglist + ' - ' | ||
59 | + else: | ||
60 | + prefix = type_ | ||
61 | + | ||
62 | + return prefix + item.get('Title') | ||
63 | + | ||
64 | + def item_description(self, item): | ||
65 | + return item.get('Description') | ||
66 | + | ||
67 | + def item_link(self, item): | ||
68 | + if item.get('Type') != 'thread': | ||
69 | + url = item.get('url') | ||
70 | + else: | ||
71 | + url = 'http://colab.interlegis.leg.br' | ||
72 | + url += item.get('url') | ||
73 | + return url | ||
74 | + |
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +from django.conf.urls.defaults import patterns, url | ||
2 | +import feeds | ||
3 | + | ||
4 | +urlpatterns = patterns('', | ||
5 | + url(r'threads/latest/$', feeds.LatestThreadsFeeds()), | ||
6 | + url(r'colab/latest/$', feeds.LatestColabFeeds()), | ||
7 | + url(r'threads/hottest/$', feeds.HottestThreadsFeeds()), | ||
8 | +) | ||
9 | + |
colab/settings.py
@@ -118,6 +118,7 @@ INSTALLED_APPS = ( | @@ -118,6 +118,7 @@ INSTALLED_APPS = ( | ||
118 | # My apps | 118 | # My apps |
119 | 'colab.super_archives', | 119 | 'colab.super_archives', |
120 | 'colab.api', | 120 | 'colab.api', |
121 | + 'colab.rss', | ||
121 | ) | 122 | ) |
122 | 123 | ||
123 | # A sample logging configuration. The only tangible logging | 124 | # A sample logging configuration. The only tangible logging |
colab/settings_local-dev.py
@@ -10,9 +10,15 @@ MANAGERS = ADMINS | @@ -10,9 +10,15 @@ MANAGERS = ADMINS | ||
10 | DATABASES = { | 10 | DATABASES = { |
11 | 'default': { | 11 | 'default': { |
12 | 'ENGINE': 'django.db.backends.sqlite3', | 12 | 'ENGINE': 'django.db.backends.sqlite3', |
13 | - 'NAME': 'colab.db', | 13 | + 'NAME': 'colab.db', |
14 | } | 14 | } |
15 | } | 15 | } |
16 | 16 | ||
17 | # Make this unique, and don't share it with anybody. | 17 | # Make this unique, and don't share it with anybody. |
18 | SECRET_KEY = ')(jksdfhsjkadfhjkh234ns!8fqu-1186h$vuj' | 18 | SECRET_KEY = ')(jksdfhsjkadfhjkh234ns!8fqu-1186h$vuj' |
19 | + | ||
20 | +import socks | ||
21 | +SOCKS_TYPE = socks.PROXY_TYPE_SOCKS5 | ||
22 | +SOCKS_SERVER = '127.0.0.1' | ||
23 | +SOCKS_PORT = 9050 | ||
24 | + |
colab/signup.py
@@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
4 | from django.conf import settings | 4 | from django.conf import settings |
5 | from django.utils.html import strip_tags | 5 | from django.utils.html import strip_tags |
6 | from django.utils.translation import ugettext as _ | 6 | from django.utils.translation import ugettext as _ |
7 | -from django.core.mail import EmailMultiAlternatives | ||
8 | from django.template.loader import render_to_string | 7 | from django.template.loader import render_to_string |
8 | +from django.core.mail import EmailMultiAlternatives, send_mail | ||
9 | 9 | ||
10 | 10 | ||
11 | def send_verification_email(request, user): | 11 | def send_verification_email(request, user): |
@@ -47,4 +47,15 @@ def send_reset_password_email(request, user): | @@ -47,4 +47,15 @@ def send_reset_password_email(request, user): | ||
47 | email_msg.attach_alternative(html_content, 'text/html') | 47 | email_msg.attach_alternative(html_content, 'text/html') |
48 | email_msg.send() | 48 | email_msg.send() |
49 | 49 | ||
50 | - | ||
51 | \ No newline at end of file | 50 | \ No newline at end of file |
51 | +def send_email_lists(user, mailing_lists): | ||
52 | + subject = _(u'Inscrição na lista de discussão') | ||
53 | + from_ = user.email | ||
54 | + to = [] | ||
55 | + for list_name in mailing_lists: | ||
56 | + # TODO: The following line needs to be generic. Domain should be stored in settings file | ||
57 | + # or database (perharps read directly from mailman). | ||
58 | + subscribe_addr = list_name + '-subscribe@listas.interlegis.gov.br' | ||
59 | + to.append(subscribe_addr) | ||
60 | + | ||
61 | + send_mail(subject, '', from_, to) | ||
62 | + |
colab/solrutils.py
@@ -178,7 +178,7 @@ def select(query, results_per_page=None, page_number=None, sort=None, fields=Non | @@ -178,7 +178,7 @@ def select(query, results_per_page=None, page_number=None, sort=None, fields=Non | ||
178 | if socks_server: | 178 | if socks_server: |
179 | import socks | 179 | import socks |
180 | logging.debug('Socks enabled: %s:%s', settings.SOCKS_SERVER, | 180 | logging.debug('Socks enabled: %s:%s', settings.SOCKS_SERVER, |
181 | - settings.SOLR_PORT) | 181 | + settings.SOCKS_PORT) |
182 | 182 | ||
183 | socks.setdefaultproxy(settings.SOCKS_TYPE, | 183 | socks.setdefaultproxy(settings.SOCKS_TYPE, |
184 | settings.SOCKS_SERVER, | 184 | settings.SOCKS_SERVER, |
colab/super_archives/forms.py
@@ -5,6 +5,7 @@ from django.core.exceptions import ValidationError | @@ -5,6 +5,7 @@ from django.core.exceptions import ValidationError | ||
5 | from django.contrib.auth.models import User | 5 | from django.contrib.auth.models import User |
6 | from django.contrib.auth.forms import UserCreationForm as UserCreationForm_ | 6 | from django.contrib.auth.forms import UserCreationForm as UserCreationForm_ |
7 | 7 | ||
8 | +from colab.super_archives.models import MailingList | ||
8 | from colab.super_archives.validators import UniqueValidator | 9 | from colab.super_archives.validators import UniqueValidator |
9 | 10 | ||
10 | # XXX: I know that this code does not look nice AT ALL. | 11 | # XXX: I know that this code does not look nice AT ALL. |
@@ -26,7 +27,20 @@ facebook_field = forms.URLField(label=u'Facebook', required=False) | @@ -26,7 +27,20 @@ facebook_field = forms.URLField(label=u'Facebook', required=False) | ||
26 | google_talk_field = forms.EmailField(label=u'Google Talk', required=False) | 27 | google_talk_field = forms.EmailField(label=u'Google Talk', required=False) |
27 | webpage_field = forms.URLField(label=u'Página Pessoal/Blog', required=False) | 28 | webpage_field = forms.URLField(label=u'Página Pessoal/Blog', required=False) |
28 | 29 | ||
29 | - | 30 | +all_lists = MailingList.objects.all() |
31 | +lists_names = [] | ||
32 | +for list_ in all_lists: | ||
33 | + choice = (list_.name, list_.name) | ||
34 | + lists_names.append(choice) | ||
35 | + | ||
36 | +lists_field = forms.MultipleChoiceField( | ||
37 | + label=u'Listas', | ||
38 | + required=False, | ||
39 | + widget=forms.CheckboxSelectMultiple, | ||
40 | + choices=lists_names | ||
41 | +) | ||
42 | + | ||
43 | + | ||
30 | class UserCreationForm(UserCreationForm_): | 44 | class UserCreationForm(UserCreationForm_): |
31 | first_name = first_name_field | 45 | first_name = first_name_field |
32 | last_name = last_name_field | 46 | last_name = last_name_field |
@@ -37,8 +51,9 @@ class UserCreationForm(UserCreationForm_): | @@ -37,8 +51,9 @@ class UserCreationForm(UserCreationForm_): | ||
37 | facebook = facebook_field | 51 | facebook = facebook_field |
38 | google_talk = google_talk_field | 52 | google_talk = google_talk_field |
39 | webpage = webpage_field | 53 | webpage = webpage_field |
54 | + lists = lists_field | ||
40 | 55 | ||
41 | - | 56 | + |
42 | class UserUpdateForm(forms.Form): | 57 | class UserUpdateForm(forms.Form): |
43 | username = username_field | 58 | username = username_field |
44 | username.required = False | 59 | username.required = False |
colab/super_archives/migrations/0008_add_mailinglist_name_to_url.py
0 → 100644
@@ -0,0 +1,142 @@ | @@ -0,0 +1,142 @@ | ||
1 | +# encoding: utf-8 | ||
2 | +import datetime | ||
3 | +from south.db import db | ||
4 | +from south.v2 import DataMigration | ||
5 | +from django.db import models | ||
6 | + | ||
7 | +class Migration(DataMigration): | ||
8 | + | ||
9 | + def forwards(self, orm): | ||
10 | + page_hits = orm.PageHit.objects.all() | ||
11 | + for page_hit in page_hits: | ||
12 | + if page_hit.url_path.startswith('/archives/thread/'): | ||
13 | + token = page_hit.url_path.split('/')[-1] | ||
14 | + threads = orm.Thread.objects.filter(subject_token=token) | ||
15 | + if not len(threads): continue | ||
16 | + thread = threads[0] | ||
17 | + new_url = '/archives/thread/%s/%s' % (thread.mailinglist.name, | ||
18 | + thread.subject_token) | ||
19 | + page_hit.url_path = new_url | ||
20 | + page_hit.save() | ||
21 | + | ||
22 | + | ||
23 | + def backwards(self, orm): | ||
24 | + raise RuntimeError("Cannot reverse this migration.") | ||
25 | + | ||
26 | + models = { | ||
27 | + 'auth.group': { | ||
28 | + 'Meta': {'object_name': 'Group'}, | ||
29 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
30 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
31 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
32 | + }, | ||
33 | + 'auth.permission': { | ||
34 | + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, | ||
35 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
36 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), | ||
37 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
38 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
39 | + }, | ||
40 | + 'auth.user': { | ||
41 | + 'Meta': {'object_name': 'User'}, | ||
42 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
43 | + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), | ||
44 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
45 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), | ||
46 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
47 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
48 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
49 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
50 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
51 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
52 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
53 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), | ||
54 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) | ||
55 | + }, | ||
56 | + 'contenttypes.contenttype': { | ||
57 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
58 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
59 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
60 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
61 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
62 | + }, | ||
63 | + 'super_archives.emailaddress': { | ||
64 | + 'Meta': {'object_name': 'EmailAddress'}, | ||
65 | + 'address': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}), | ||
66 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
67 | + 'md5': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), | ||
68 | + 'real_name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '64', 'blank': 'True'}), | ||
69 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emails'", 'null': 'True', 'to': "orm['auth.User']"}) | ||
70 | + }, | ||
71 | + 'super_archives.mailinglist': { | ||
72 | + 'Meta': {'object_name': 'MailingList'}, | ||
73 | + 'description': ('django.db.models.fields.TextField', [], {}), | ||
74 | + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), | ||
75 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
76 | + 'last_imported_index': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
77 | + 'logo': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), | ||
78 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}) | ||
79 | + }, | ||
80 | + 'super_archives.mailinglistmembership': { | ||
81 | + 'Meta': {'object_name': 'MailingListMembership'}, | ||
82 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
83 | + 'mailinglist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.MailingList']"}), | ||
84 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) | ||
85 | + }, | ||
86 | + 'super_archives.message': { | ||
87 | + 'Meta': {'object_name': 'Message'}, | ||
88 | + 'body': ('django.db.models.fields.TextField', [], {'default': "''"}), | ||
89 | + 'from_address': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.EmailAddress']"}), | ||
90 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
91 | + 'mailinglist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.MailingList']"}), | ||
92 | + 'message_id': ('django.db.models.fields.CharField', [], {'max_length': '512'}), | ||
93 | + 'received_time': ('django.db.models.fields.DateTimeField', [], {}), | ||
94 | + 'spam': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
95 | + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}), | ||
96 | + 'subject_clean': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}), | ||
97 | + 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.Thread']", 'null': 'True'}) | ||
98 | + }, | ||
99 | + 'super_archives.messagemetadata': { | ||
100 | + 'Message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.Message']"}), | ||
101 | + 'Meta': {'object_name': 'MessageMetadata'}, | ||
102 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
103 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), | ||
104 | + 'value': ('django.db.models.fields.TextField', [], {}) | ||
105 | + }, | ||
106 | + 'super_archives.pagehit': { | ||
107 | + 'Meta': {'object_name': 'PageHit'}, | ||
108 | + 'hit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
109 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
110 | + 'url_path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '2048', 'db_index': 'True'}) | ||
111 | + }, | ||
112 | + 'super_archives.thread': { | ||
113 | + 'Meta': {'unique_together': "(('subject_token', 'mailinglist'),)", 'object_name': 'Thread'}, | ||
114 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
115 | + 'latest_message': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['super_archives.Message']"}), | ||
116 | + 'mailinglist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.MailingList']"}), | ||
117 | + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
118 | + 'spam': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
119 | + 'subject_token': ('django.db.models.fields.CharField', [], {'max_length': '512'}) | ||
120 | + }, | ||
121 | + 'super_archives.userprofile': { | ||
122 | + 'Meta': {'object_name': 'UserProfile'}, | ||
123 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), | ||
124 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True'}), | ||
125 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
126 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), | ||
127 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), | ||
128 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), | ||
129 | + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}), | ||
130 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), | ||
131 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256'}) | ||
132 | + }, | ||
133 | + 'super_archives.vote': { | ||
134 | + 'Meta': {'unique_together': "(('user', 'message'),)", 'object_name': 'Vote'}, | ||
135 | + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), | ||
136 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
137 | + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['super_archives.Message']"}), | ||
138 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) | ||
139 | + } | ||
140 | + } | ||
141 | + | ||
142 | + complete_apps = ['super_archives'] |
colab/super_archives/models.py
@@ -148,7 +148,8 @@ class Thread(models.Model): | @@ -148,7 +148,8 @@ class Thread(models.Model): | ||
148 | 148 | ||
149 | # Calculate page_view_score | 149 | # Calculate page_view_score |
150 | try: | 150 | try: |
151 | - url = reverse('thread_view', args=[self.subject_token]) | 151 | + url = reverse('thread_view', args=[self.mailinglist.name, |
152 | + self.subject_token]) | ||
152 | pagehit = PageHit.objects.get(url_path=url) | 153 | pagehit = PageHit.objects.get(url_path=url) |
153 | page_view_score = pagehit.hit_count * 10 | 154 | page_view_score = pagehit.hit_count * 10 |
154 | except (NoReverseMatch, PageHit.DoesNotExist): | 155 | except (NoReverseMatch, PageHit.DoesNotExist): |
@@ -217,7 +218,8 @@ class Message(models.Model): | @@ -217,7 +218,8 @@ class Message(models.Model): | ||
217 | @property | 218 | @property |
218 | def url(self): | 219 | def url(self): |
219 | """Shortcut to get thread url""" | 220 | """Shortcut to get thread url""" |
220 | - return reverse('thread_view', args=[self.thread.subject_token]) | 221 | + return reverse('thread_view', args=[self.mailinglist.name, |
222 | + self.thread.subject_token]) | ||
221 | 223 | ||
222 | @property | 224 | @property |
223 | def Description(self): | 225 | def Description(self): |
colab/super_archives/queries.py
@@ -26,15 +26,18 @@ def get_messages_by_voted(): | @@ -26,15 +26,18 @@ def get_messages_by_voted(): | ||
26 | return messages.order_by('-vote_count', 'received_time') | 26 | return messages.order_by('-vote_count', 'received_time') |
27 | 27 | ||
28 | 28 | ||
29 | -def get_first_message_in_thread(thread_token): | ||
30 | - return get_messages_by_date().filter(thread__subject_token=thread_token)[0] | ||
31 | - | 29 | +def get_first_message_in_thread(mailinglist, thread_token): |
30 | + query = get_messages_by_date() | ||
31 | + query = query.filter(mailinglist__name=mailinglist) | ||
32 | + query = query.filter(thread__subject_token=thread_token)[0] | ||
33 | + return query | ||
34 | + | ||
32 | 35 | ||
33 | def get_latest_threads(): | 36 | def get_latest_threads(): |
34 | return Thread.objects.order_by('-latest_message__received_time') | 37 | return Thread.objects.order_by('-latest_message__received_time') |
35 | 38 | ||
36 | 39 | ||
37 | -def get_hotest_threads(): | 40 | +def get_hottest_threads(): |
38 | return Thread.objects.order_by('-score', '-latest_message__received_time') | 41 | return Thread.objects.order_by('-score', '-latest_message__received_time') |
39 | 42 | ||
40 | 43 |
colab/super_archives/templates/message-list.html
@@ -11,8 +11,8 @@ | @@ -11,8 +11,8 @@ | ||
11 | 11 | ||
12 | <h4>Ordenar por</h4> | 12 | <h4>Ordenar por</h4> |
13 | <ul> | 13 | <ul> |
14 | - <li {% ifequal order_by "hotest" %} class="selected" title="{% trans "Retirar filtro" %}" {% endifequal %}> | ||
15 | - <a href="{% ifequal order_by "hotest" %} {% append_to_get order="",p=1 %} {% else %} {% append_to_get order='hotest',p=1 %} {% endifequal %}"> | 14 | + <li {% ifequal order_by "hottest" %} class="selected" title="{% trans "Retirar filtro" %}" {% endifequal %}> |
15 | + <a href="{% ifequal order_by "hottest" %} {% append_to_get order="",p=1 %} {% else %} {% append_to_get order='hottest',p=1 %} {% endifequal %}"> | ||
16 | Relevância</a></li> | 16 | Relevância</a></li> |
17 | <li {% ifequal order_by "latest" %} class="selected" title="{% trans "Retirar filtro" %}" {% endifequal %}> | 17 | <li {% ifequal order_by "latest" %} class="selected" title="{% trans "Retirar filtro" %}" {% endifequal %}> |
18 | <a href="{% ifequal order_by "latest" %} {% append_to_get order="",p=1 %} {% else %} {% append_to_get order='latest',p=1 %} {% endifequal %}"> | 18 | <a href="{% ifequal order_by "latest" %} {% append_to_get order="",p=1 %} {% else %} {% append_to_get order='latest',p=1 %} {% endifequal %}"> |
colab/super_archives/templatetags/append_to_get.py
@@ -37,7 +37,16 @@ class AppendGetNode(template.Node): | @@ -37,7 +37,16 @@ class AppendGetNode(template.Node): | ||
37 | path = context['request'].META['PATH_INFO'] | 37 | path = context['request'].META['PATH_INFO'] |
38 | 38 | ||
39 | if len(get): | 39 | if len(get): |
40 | - path = '?' + urllib.urlencode(get) | 40 | + # Convert all unicode objects in the get dict to |
41 | + # str (utf-8 encoded) | ||
42 | + get_utf_encoded = {} | ||
43 | + for (key, value) in get.items(): | ||
44 | + if isinstance(value, unicode): | ||
45 | + value = value.encode('utf-8') | ||
46 | + get_utf_encoded.update({key: value}) | ||
47 | + get_utf_encoded = dict(get_utf_encoded) | ||
48 | + | ||
49 | + path = '?' + urllib.urlencode(get_utf_encoded) | ||
41 | 50 | ||
42 | return path | 51 | return path |
43 | 52 |
colab/super_archives/templatetags/form_field.py
@@ -24,40 +24,41 @@ class RenderFormField(template.Node): | @@ -24,40 +24,41 @@ class RenderFormField(template.Node): | ||
24 | def render(self, context): | 24 | def render(self, context): |
25 | editable = context.get('editable', True) | 25 | editable = context.get('editable', True) |
26 | 26 | ||
27 | - class_ = '' | ||
28 | - errors = '' | ||
29 | - form_field_tag = '' | 27 | + class_ = u'' |
28 | + errors = u'' | ||
29 | + form_field_tag = u'' | ||
30 | try: | 30 | try: |
31 | form_field = self.form_field_nocontext.resolve(context) | 31 | form_field = self.form_field_nocontext.resolve(context) |
32 | except template.VariableDoesNotExist: | 32 | except template.VariableDoesNotExist: |
33 | - return '' | 33 | + return u'' |
34 | 34 | ||
35 | if form_field.errors: | 35 | if form_field.errors: |
36 | - class_ += 'error' | 36 | + class_ += u'error' |
37 | if form_field.field.required: | 37 | if form_field.field.required: |
38 | - class_ += ' required' | 38 | + class_ += u' required' |
39 | if form_field.errors: | 39 | if form_field.errors: |
40 | - errors = '<br/>' + form_field.errors.as_text() | 40 | + errors = u'<br/>' + form_field.errors.as_text() |
41 | 41 | ||
42 | try: | 42 | try: |
43 | default_value = self.default_value_nocontext.resolve(context) | 43 | default_value = self.default_value_nocontext.resolve(context) |
44 | except template.VariableDoesNotExist: | 44 | except template.VariableDoesNotExist: |
45 | - default_value = '' | 45 | + default_value = u'' |
46 | 46 | ||
47 | if editable: | 47 | if editable: |
48 | - form_field_tag = '<br/>' + str(form_field) | 48 | + form_field_tag = u'<br/>' + unicode(form_field) |
49 | elif isinstance(form_field.field, forms.URLField): | 49 | elif isinstance(form_field.field, forms.URLField): |
50 | - form_field_tag = """<a href="%s" target="_blank">%s</a>""" % ( | 50 | + form_field_tag = u"""<a href="%s" target="_blank">%s</a>""" % ( |
51 | default_value, default_value) | 51 | default_value, default_value) |
52 | else: | 52 | else: |
53 | form_field_tag = default_value | 53 | form_field_tag = default_value |
54 | 54 | ||
55 | - return """<p class="%s">%s: %s %s</p>""" % ( | 55 | + return u"""<p class="%s">%s: %s %s</p>""" % ( |
56 | class_, | 56 | class_, |
57 | form_field.label_tag(), | 57 | form_field.label_tag(), |
58 | form_field_tag, | 58 | form_field_tag, |
59 | errors | 59 | errors |
60 | ) | 60 | ) |
61 | - | 61 | + |
62 | + | ||
62 | register = template.Library() | 63 | register = template.Library() |
63 | register.tag('render_form_field', render_form_field) | 64 | register.tag('render_form_field', render_form_field) |
colab/super_archives/urls.py
@@ -2,7 +2,7 @@ from django.conf.urls.defaults import patterns, include, url | @@ -2,7 +2,7 @@ from django.conf.urls.defaults import patterns, include, url | ||
2 | 2 | ||
3 | urlpatterns = patterns('', | 3 | urlpatterns = patterns('', |
4 | # url(r'thread/(?P<thread>\d+)/$', 'super_archives.views.thread', name='thread'), | 4 | # url(r'thread/(?P<thread>\d+)/$', 'super_archives.views.thread', name='thread'), |
5 | - url(r'thread/(?P<thread_token>[-\w]+)$', | 5 | + url(r'thread/(?P<mailinglist>[-\w]+)/(?P<thread_token>[-\w]+)$', |
6 | 'colab.super_archives.views.thread', name="thread_view"), | 6 | 'colab.super_archives.views.thread', name="thread_view"), |
7 | url(r'thread/$', | 7 | url(r'thread/$', |
8 | 'colab.super_archives.views.list_messages', name='thread_list') | 8 | 'colab.super_archives.views.list_messages', name='thread_list') |
colab/super_archives/views.py
@@ -8,9 +8,9 @@ from colab.super_archives import queries | @@ -8,9 +8,9 @@ from colab.super_archives import queries | ||
8 | from colab.super_archives.models import MailingList, Thread | 8 | from colab.super_archives.models import MailingList, Thread |
9 | 9 | ||
10 | 10 | ||
11 | -def thread(request, thread_token): | 11 | +def thread(request, mailinglist, thread_token): |
12 | 12 | ||
13 | - first_message = queries.get_first_message_in_thread(thread_token) | 13 | + first_message = queries.get_first_message_in_thread(mailinglist, thread_token) |
14 | order_by = request.GET.get('order') | 14 | order_by = request.GET.get('order') |
15 | if order_by == 'voted': | 15 | if order_by == 'voted': |
16 | msgs_query = queries.get_messages_by_voted() | 16 | msgs_query = queries.get_messages_by_voted() |
@@ -18,6 +18,7 @@ def thread(request, thread_token): | @@ -18,6 +18,7 @@ def thread(request, thread_token): | ||
18 | msgs_query = queries.get_messages_by_date() | 18 | msgs_query = queries.get_messages_by_date() |
19 | 19 | ||
20 | msgs_query = msgs_query.filter(thread__subject_token=thread_token) | 20 | msgs_query = msgs_query.filter(thread__subject_token=thread_token) |
21 | + msgs_query = msgs_query.filter(mailinglist__name=mailinglist) | ||
21 | emails = msgs_query.exclude(id=first_message.id) | 22 | emails = msgs_query.exclude(id=first_message.id) |
22 | 23 | ||
23 | total_votes = first_message.votes_count() | 24 | total_votes = first_message.votes_count() |
@@ -25,7 +26,8 @@ def thread(request, thread_token): | @@ -25,7 +26,8 @@ def thread(request, thread_token): | ||
25 | total_votes += email.votes_count() | 26 | total_votes += email.votes_count() |
26 | 27 | ||
27 | # Update relevance score | 28 | # Update relevance score |
28 | - thread = Thread.objects.get(subject_token=thread_token) | 29 | + query = Thread.objects.filter(mailinglist__name=mailinglist) |
30 | + thread = query.get(subject_token=thread_token) | ||
29 | thread.update_score() | 31 | thread.update_score() |
30 | 32 | ||
31 | template_data = { | 33 | template_data = { |
@@ -44,8 +46,8 @@ def list_messages(request): | @@ -44,8 +46,8 @@ def list_messages(request): | ||
44 | selected_list = request.GET.get('list') | 46 | selected_list = request.GET.get('list') |
45 | 47 | ||
46 | order_by = request.GET.get('order') | 48 | order_by = request.GET.get('order') |
47 | - if order_by == 'hotest': | ||
48 | - threads = queries.get_hotest_threads() | 49 | + if order_by == 'hottest': |
50 | + threads = queries.get_hottest_threads() | ||
49 | else: | 51 | else: |
50 | threads = queries.get_latest_threads() | 52 | threads = queries.get_latest_threads() |
51 | 53 |
colab/templates/home.html
@@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
18 | {% block main-content %} | 18 | {% block main-content %} |
19 | 19 | ||
20 | <div class="span-12 colborder"> | 20 | <div class="span-12 colborder"> |
21 | - <h3>{% trans "Últimas Colaborações:" %}</h3> | 21 | + <h3>{% trans "Últimas Colaborações" %}</h3> |
22 | <ul> | 22 | <ul> |
23 | {% for doc in latest_docs %} | 23 | {% for doc in latest_docs %} |
24 | {% include "message-preview.html" %} | 24 | {% include "message-preview.html" %} |
@@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
31 | </div> | 31 | </div> |
32 | 32 | ||
33 | <div class="span-11 last"> | 33 | <div class="span-11 last"> |
34 | - <h3>{% trans "Distribuição das Colaborações:" %}</h3> | 34 | + <h3>{% trans "Distribuição das Colaborações" %}</h3> |
35 | <div id="collabs"></div> | 35 | <div id="collabs"></div> |
36 | </div> | 36 | </div> |
37 | 37 | ||
@@ -39,20 +39,20 @@ | @@ -39,20 +39,20 @@ | ||
39 | <hr/> | 39 | <hr/> |
40 | 40 | ||
41 | <div class="span-12 colborder"> | 41 | <div class="span-12 colborder"> |
42 | - <h3>{% trans "Discussões Mais Relevantes:" %}</h3> | 42 | + <h3>{% trans "Discussões Mais Relevantes" %}</h3> |
43 | <ul> | 43 | <ul> |
44 | - {% for thread in hotest_threads %} | 44 | + {% for thread in hottest_threads %} |
45 | {% include "message-preview.html" with doc=thread.latest_message %} | 45 | {% include "message-preview.html" with doc=thread.latest_message %} |
46 | {% endfor %} | 46 | {% endfor %} |
47 | </ul> | 47 | </ul> |
48 | <hr class="space"/> | 48 | <hr class="space"/> |
49 | - <a class="right" href="{% url thread_list %}?order=hotest"> | 49 | + <a class="right" href="{% url thread_list %}?order=hottest"> |
50 | {% trans "Ver mais discussões relevantes..." %} | 50 | {% trans "Ver mais discussões relevantes..." %} |
51 | </a> | 51 | </a> |
52 | </div> | 52 | </div> |
53 | 53 | ||
54 | <div class="span-11 last"> | 54 | <div class="span-11 last"> |
55 | - <h3>{% trans "Últimas Discussões:" %}</h3> | 55 | + <h3>{% trans "Últimas Discussões" %}</h3> |
56 | <ul> | 56 | <ul> |
57 | {% for thread in latest_threads %} | 57 | {% for thread in latest_threads %} |
58 | {% include "message-preview.html" with doc=thread.latest_message %} | 58 | {% include "message-preview.html" with doc=thread.latest_message %} |
colab/templates/signup-form.html
@@ -54,7 +54,12 @@ | @@ -54,7 +54,12 @@ | ||
54 | {% render_form_field form.google_talk %} | 54 | {% render_form_field form.google_talk %} |
55 | {% render_form_field form.webpage %} | 55 | {% render_form_field form.webpage %} |
56 | </fieldset> | 56 | </fieldset> |
57 | - | 57 | + |
58 | + <fieldset class="box span-11"> | ||
59 | + <legend>Inscrever-se nas Listas</legend> | ||
60 | + {% render_form_field form.lists %} | ||
61 | + </fieldset> | ||
62 | + | ||
58 | <div class="span-24"> | 63 | <div class="span-24"> |
59 | <input class="right" type="submit" value="Cadastrar"/> | 64 | <input class="right" type="submit" value="Cadastrar"/> |
60 | </div> | 65 | </div> |
colab/templates/user-profile.html
@@ -9,20 +9,20 @@ | @@ -9,20 +9,20 @@ | ||
9 | {% block main-content %} | 9 | {% block main-content %} |
10 | {% if not user_profile %} | 10 | {% if not user_profile %} |
11 | <span class="notice span-24"> | 11 | <span class="notice span-24"> |
12 | - <b>Usuário não cadastrado.</b> Você é dono deste perfil? | 12 | + <b>Usuário não cadastrado.</b> Você é dono deste perfil? |
13 | <a href="{% url signup %}">Clique aqui | 13 | <a href="{% url signup %}">Clique aqui |
14 | e cadastre-se.</a> | 14 | e cadastre-se.</a> |
15 | </span> | 15 | </span> |
16 | 16 | ||
17 | - {% else %} | ||
18 | - | 17 | + {% else %} |
18 | + | ||
19 | {% ifequal request.user.username user_profile.user.username %} | 19 | {% ifequal request.user.username user_profile.user.username %} |
20 | <span class="success span-24"> | 20 | <span class="success span-24"> |
21 | - Ei, olha você aqui! Quer | 21 | + Ei, olha você aqui! Quer |
22 | <a href="{% url user_profile_update request.user %}">editar seu perfil</a>? | 22 | <a href="{% url user_profile_update request.user %}">editar seu perfil</a>? |
23 | </span> | 23 | </span> |
24 | {% endifequal %} | 24 | {% endifequal %} |
25 | - | 25 | + |
26 | {% endif %} | 26 | {% endif %} |
27 | 27 | ||
28 | <div id="user-profile"> | 28 | <div id="user-profile"> |
@@ -32,12 +32,12 @@ | @@ -32,12 +32,12 @@ | ||
32 | <img class="avatar" width="120px" heigth="120px" | 32 | <img class="avatar" width="120px" heigth="120px" |
33 | src="http://www.gravatar.com/avatar/{{ email_address.md5 }}?s=120&d=identicon" /> | 33 | src="http://www.gravatar.com/avatar/{{ email_address.md5 }}?s=120&d=identicon" /> |
34 | </div> | 34 | </div> |
35 | - | 35 | + |
36 | <div class="span-20 last"> | 36 | <div class="span-20 last"> |
37 | <div class="span-10"> | 37 | <div class="span-10"> |
38 | <form action="{% url user_profile_update request.user %}" method='post'> | 38 | <form action="{% url user_profile_update request.user %}" method='post'> |
39 | {% csrf_token %} | 39 | {% csrf_token %} |
40 | - | 40 | + |
41 | <h3>Informações Pessoais</h3> | 41 | <h3>Informações Pessoais</h3> |
42 | <ul id="user-info"> | 42 | <ul id="user-info"> |
43 | <li> | 43 | <li> |
@@ -53,9 +53,9 @@ | @@ -53,9 +53,9 @@ | ||
53 | {% render_form_field form.role user_profile.role %} | 53 | {% render_form_field form.role user_profile.role %} |
54 | </li> | 54 | </li> |
55 | </ul> | 55 | </ul> |
56 | - | 56 | + |
57 | <hr class="space" /> | 57 | <hr class="space" /> |
58 | - | 58 | + |
59 | <h3>Outras Informações</h3> | 59 | <h3>Outras Informações</h3> |
60 | <ul> | 60 | <ul> |
61 | <li> | 61 | <li> |
@@ -71,7 +71,7 @@ | @@ -71,7 +71,7 @@ | ||
71 | {% render_form_field form.webpage user_profile.webpage %} | 71 | {% render_form_field form.webpage user_profile.webpage %} |
72 | </li> | 72 | </li> |
73 | </ul> | 73 | </ul> |
74 | - | 74 | + |
75 | <hr class="space"/> | 75 | <hr class="space"/> |
76 | {% if editable %} | 76 | {% if editable %} |
77 | <span class="span-5"> | 77 | <span class="span-5"> |
@@ -80,30 +80,30 @@ | @@ -80,30 +80,30 @@ | ||
80 | {% endif %} | 80 | {% endif %} |
81 | </form> | 81 | </form> |
82 | </div> | 82 | </div> |
83 | - | 83 | + |
84 | {% if type_count %} | 84 | {% if type_count %} |
85 | <div class="span-10 last"> | 85 | <div class="span-10 last"> |
86 | - <h3 class="center">{% trans "Colaborações por área" %}</h3> | 86 | + <h3 class="center">{% trans "Colaborações por Área" %}</h3> |
87 | <div id="collabs"></div> | 87 | <div id="collabs"></div> |
88 | </div> | 88 | </div> |
89 | {% endif %} | 89 | {% endif %} |
90 | </div> | 90 | </div> |
91 | - | 91 | + |
92 | <hr class="space" /> | 92 | <hr class="space" /> |
93 | - | 93 | + |
94 | <div class="span-13"> | 94 | <div class="span-13"> |
95 | - <h3>{% trans "Últimas mensagens enviadas" %} </h3> | 95 | + <h3>{% trans "Últimas Mensagens Enviadas" %} </h3> |
96 | <ul class="colborder"> | 96 | <ul class="colborder"> |
97 | {% for doc in emails %} | 97 | {% for doc in emails %} |
98 | {% include "message-preview.html" %} | 98 | {% include "message-preview.html" %} |
99 | {% empty %} | 99 | {% empty %} |
100 | <li>Não existem mensagens enviadas por este usuário até o momento.</li> | 100 | <li>Não existem mensagens enviadas por este usuário até o momento.</li> |
101 | - {% endfor %} | 101 | + {% endfor %} |
102 | </ul> | 102 | </ul> |
103 | </div> | 103 | </div> |
104 | - | 104 | + |
105 | <div class="span-11 last"> | 105 | <div class="span-11 last"> |
106 | - <h3>{% trans "Participações na comunidade:" %}</h3> | 106 | + <h3>{% trans "Participações na Comunidade" %}</h3> |
107 | <ul> | 107 | <ul> |
108 | {% for doc in docs %} | 108 | {% for doc in docs %} |
109 | {% include "message-preview.html" %} | 109 | {% include "message-preview.html" %} |
@@ -112,6 +112,6 @@ | @@ -112,6 +112,6 @@ | ||
112 | {% endfor %} | 112 | {% endfor %} |
113 | </ul> | 113 | </ul> |
114 | </div> | 114 | </div> |
115 | - | 115 | + |
116 | </div> | 116 | </div> |
117 | {% endblock %} | 117 | {% endblock %} |
colab/urls.py
@@ -10,6 +10,8 @@ urlpatterns = patterns('', | @@ -10,6 +10,8 @@ urlpatterns = patterns('', | ||
10 | url(r'^archives/', include('colab.super_archives.urls')), | 10 | url(r'^archives/', include('colab.super_archives.urls')), |
11 | 11 | ||
12 | url(r'^api/', include('colab.api.urls')), | 12 | url(r'^api/', include('colab.api.urls')), |
13 | + | ||
14 | + url(r'^rss/', include('colab.rss.urls')), | ||
13 | 15 | ||
14 | url(r'^user/(?P<username>[\w@+.-]+)/?$', | 16 | url(r'^user/(?P<username>[\w@+.-]+)/?$', |
15 | 'colab.views.userprofile.by_username', name='user_profile'), | 17 | 'colab.views.userprofile.by_username', name='user_profile'), |
@@ -45,7 +47,7 @@ urlpatterns = patterns('', | @@ -45,7 +47,7 @@ urlpatterns = patterns('', | ||
45 | 47 | ||
46 | url(r'^account/logout/$', 'django.contrib.auth.views.logout', | 48 | url(r'^account/logout/$', 'django.contrib.auth.views.logout', |
47 | {'next_page': '/'}, name='logout'), | 49 | {'next_page': '/'}, name='logout'), |
48 | - | 50 | + |
49 | # Uncomment the next line to enable the admin: | 51 | # Uncomment the next line to enable the admin: |
50 | url(r'^colab/admin/', include(admin.site.urls)), | 52 | url(r'^colab/admin/', include(admin.site.urls)), |
51 | ) | 53 | ) |
colab/views/other.py
@@ -18,10 +18,10 @@ def home(request): | @@ -18,10 +18,10 @@ def home(request): | ||
18 | """Index page view""" | 18 | """Index page view""" |
19 | 19 | ||
20 | latest_threads = queries.get_latest_threads() | 20 | latest_threads = queries.get_latest_threads() |
21 | - hotest_threads = queries.get_hotest_threads() | 21 | + hottest_threads = queries.get_hottest_threads() |
22 | 22 | ||
23 | template_data = { | 23 | template_data = { |
24 | - 'hotest_threads': hotest_threads[:6], | 24 | + 'hottest_threads': hottest_threads[:6], |
25 | 'latest_threads': latest_threads[:6], | 25 | 'latest_threads': latest_threads[:6], |
26 | 'type_count': solrutils.count_types(sample=1000), | 26 | 'type_count': solrutils.count_types(sample=1000), |
27 | 'latest_docs': solrutils.get_latest_collaborations(6), | 27 | 'latest_docs': solrutils.get_latest_collaborations(6), |
colab/views/signup.py
@@ -60,6 +60,11 @@ def signup(request): | @@ -60,6 +60,11 @@ def signup(request): | ||
60 | 60 | ||
61 | signup_.send_verification_email(request, user) | 61 | signup_.send_verification_email(request, user) |
62 | 62 | ||
63 | + mailing_lists = form.cleaned_data.get('lists') | ||
64 | + if mailing_lists: | ||
65 | + signup_.send_email_lists(user, mailing_lists) | ||
66 | + | ||
67 | + | ||
63 | # Check if the user's email have been used previously | 68 | # Check if the user's email have been used previously |
64 | # in the mainling lists to link the user to old messages | 69 | # in the mainling lists to link the user to old messages |
65 | email_addr, created = EmailAddress.objects.get_or_create(address=user.email) | 70 | email_addr, created = EmailAddress.objects.get_or_create(address=user.email) |
solr-conf/data-config.xml
@@ -321,7 +321,8 @@ | @@ -321,7 +321,8 @@ | ||
321 | <field column="UID" template="THREAD_${thread.id}" /> | 321 | <field column="UID" template="THREAD_${thread.id}" /> |
322 | <field column="getId" template="${thread.name}" /> | 322 | <field column="getId" template="${thread.name}" /> |
323 | <field column="Type" template="thread" /> | 323 | <field column="Type" template="thread" /> |
324 | - <field column="path_string" template="/archives/thread/${thread.name}" /> | 324 | + <field column="path_string" |
325 | + template="/archives/thread/${thread.mailinglist}/${thread.name}" /> | ||
325 | <field column="created" name="created" | 326 | <field column="created" name="created" |
326 | dateTimeFormat="yyyy-MM-dd hh:mm:ss" /> | 327 | dateTimeFormat="yyyy-MM-dd hh:mm:ss" /> |
327 | <field column="modified" name="modified" | 328 | <field column="modified" name="modified" |