Commit f8747b748b3e235cb540718ea284a27202f52f2f

Authored by Luan
2 parents 5a17864f fd7bc7d3

Merge branch 'master' into haystack

fabfile.py
... ... @@ -19,6 +19,11 @@ environments = {
19 19 'hosts': [], #TODO
20 20 'key_filename': '~/.ssh/id_rsa',
21 21 },
  22 + 'demo': {
  23 + 'hosts': ['colab-demo.tracy.com.br'],
  24 + 'key_filename': '~/.ssh/id_rsa',
  25 + 'port': 22,
  26 + },
22 27 }
23 28  
24 29  
... ... @@ -27,8 +32,8 @@ WORKON_COLAB = '{} && workon colab'.format(SOURCE_VENV)
27 32  
28 33  
29 34 def environment(name):
30   - env.update(environments[name])
31   - env.environment = name
  35 + env.update(environments[name])
  36 + env.environment = name
32 37 environment('dev')
33 38  
34 39  
... ... @@ -48,6 +53,15 @@ def install(local_settings=None):
48 53 if local_settings:
49 54 put(local_settings, '~/colab/src/colab/local_settings.py')
50 55  
  56 + if not exists('~/apache-solr-3.6.2/'):
  57 + run('wget http://archive.apache.org/dist/lucene/solr/3.6.2/apache-solr-3.6.2.tgz')
  58 + run('tar xzf apache-solr-3.6.2.tgz')
  59 + run('rm apache-solr-3.6.2.tgz')
  60 +
  61 + with cd('~/apache-solr-3.6.2/example/solr/conf/'):
  62 + if not exists('stopwords_en.txt'):
  63 + run('cp stopwords.txt stopwords_en.txt')
  64 +
51 65 if env_created:
52 66 update_requirements()
53 67  
... ... @@ -56,7 +70,7 @@ def install(local_settings=None):
56 70  
57 71 def update_requirements():
58 72 with cd('~/colab'), prefix(WORKON_COLAB):
59   - run('pip install -r requirements.txt')
  73 + run('pip install -U -r requirements.txt')
60 74  
61 75  
62 76 def deploy(update=False):
... ... @@ -71,10 +85,20 @@ def deploy(update=False):
71 85 run('python manage.py syncdb')
72 86 run('python manage.py migrate')
73 87 run('python manage.py collectstatic --noinput')
  88 + run('python manage.py build_solr_schema -f ~/apache-solr-3.6.2/example/solr/conf/schema.xml')
74 89  
75 90 sudo('supervisorctl restart all')
76 91  
77 92  
  93 +def rebuild_index(age=None):
  94 + with cd('~/colab/src/'), prefix(WORKON_COLAB):
  95 + age_arg = ''
  96 + if age:
  97 + age_arg = '--age={}'.format(age)
  98 +
  99 + run('python manage.py rebuild_index {}'.format(age_arg))
  100 +
  101 +
78 102 @with_settings(user='vagrant')
79 103 def runserver(update_requirements=False):
80 104 env_created = mkvirtualenv()
... ...
puppet/modules/colab/manifests/init.pp
... ... @@ -56,6 +56,12 @@ class colab {
56 56 user => 'colab',
57 57 }
58 58  
  59 + supervisor::app { 'solr':
  60 + command => 'java -jar start.jar',
  61 + directory => '/home/colab/apache-solr-3.6.2/example',
  62 + user => 'colab',
  63 + }
  64 +
59 65 nginx::config { 'nginx':
60 66 content => template('colab/nginx/extra_conf.erb'),
61 67 }
... ...
puppet/modules/colab/manifests/requirements.pp
... ... @@ -42,7 +42,7 @@ class colab::requirements {
42 42 provider => pip,
43 43 require => [Package['python-pip'], Package['python-dev'], Package['build-essential']],
44 44 }
45   -
  45 +
46 46 # links virtualenvwrapper to load automaticaly
47 47 file { '/etc/bash_completion.d/virtualenvwrapper.sh':
48 48 ensure => link,
... ... @@ -58,7 +58,7 @@ class colab::requirements {
58 58 package { 'python-dev':
59 59 ensure => installed,
60 60 }
61   -
  61 +
62 62 # req by gvent
63 63 package { 'libevent-dev':
64 64 ensure => installed,
... ... @@ -83,4 +83,9 @@ class colab::requirements {
83 83 package { 'gettext':
84 84 ensure => installed,
85 85 }
  86 +
  87 + # req by solr
  88 + package { 'openjdk-7-jre':
  89 + ensure => installed,
  90 + }
86 91 }
... ...
requirements.txt
... ... @@ -9,6 +9,7 @@ python-dateutil==1.5
9 9 django-cliauth==0.9
10 10 django-mobile==0.3.0
11 11 django-haystack==2.1
  12 +pysolr==2.1
12 13 etiquetando==0.1
13 14 html2text
14 15 django-taggit
... ...
src/accounts/search_indexes.py
... ... @@ -30,9 +30,8 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable):
30 30 return 'date_joined'
31 31  
32 32 def prepare_description(self, obj):
33   - return u'{}\n{}\n{}\n{}\n{}\n{}'.format(
34   - obj.institution, obj.role, obj.username, obj.get_full_name(),
35   - obj.google_talk, obj.webpage
  33 + return u'{}\n{}\n{}\n{}'.format(
  34 + obj.institution, obj.role, obj.username, obj.get_full_name()
36 35 )
37 36  
38 37 def prepare_icon_name(self, obj):
... ...
src/colab/custom_settings.py
... ... @@ -56,8 +56,8 @@ DATABASES = {
56 56 },
57 57 'trac': {
58 58 'ENGINE': 'django.db.backends.postgresql_psycopg2',
59   - 'NAME': 'trac',
60   - 'USER': 'trac',
  59 + 'NAME': 'trac_colab',
  60 + 'USER': 'colab',
61 61 'PASSWORD': os.environ.get('COLAB_TRAC_DB_PWD'),
62 62 'HOST': os.environ.get('COLAB_TRAC_DB_HOST'),
63 63 }
... ... @@ -97,7 +97,7 @@ LOGGING = {
97 97 'disable_existing_loggers': False,
98 98 'root': {
99 99 'level': 'WARNING',
100   - 'handlers': ['sentry'],
  100 + 'handlers': ['sentry', 'console'],
101 101 },
102 102 'formatters': {
103 103 'verbose': {
... ... @@ -209,6 +209,8 @@ LOCALE_PATHS = (
209 209  
210 210 AUTH_USER_MODEL = 'accounts.User'
211 211  
  212 +ALLOWED_HOSTS = ['colab.interlegis.leg.br']
  213 +
212 214 from django.contrib.messages import constants as messages
213 215 MESSAGE_TAGS = {
214 216 messages.INFO: 'alert-info',
... ... @@ -227,6 +229,8 @@ FEEDZILLA_SITE_DESCRIPTION = gettext(u'Colab blog aggregator')
227 229  
228 230 ### BrowserID / Persona
229 231 SITE_URL = 'https://colab.interlegis.leg.br'
  232 +BROWSERID_AUDIENCES = [SITE_URL]
  233 +
230 234  
231 235 LOGIN_URL = '/'
232 236 LOGIN_REDIRECT_URL = '/'
... ... @@ -235,27 +239,20 @@ LOGOUT_REDIRECT_URL = '/'
235 239 BROWSERID_CREATE_USER = False
236 240  
237 241  
238   -### Apache Solr
239   -#SOLR_HOSTNAME = 'solr.interlegis.leg.br'
240   -SOLR_HOSTNAME = '10.1.2.154'
241   -SOLR_PORT = '8080'
242   -SOLR_SELECT_PATH = '/solr/select'
243   -
244   -SOLR_COLAB_URI = 'http://colab.interlegis.leg.br'
245   -SOLR_BASE_QUERY = """
246   - ((Type:changeset OR Type:ticket OR Type:wiki OR Type:thread) AND Title:["" TO *])
247   -"""
248   -
  242 +## Proxy settings
249 243 COLAB_TRAC_URL = 'http://colab-backend.interlegis.leg.br/'
250 244 COLAB_CI_URL = 'http://jenkins.interlegis.leg.br:8080/ci/'
251 245  
252 246 REVPROXY_ADD_REMOTE_USER = True
253 247  
  248 +
  249 +## Converse.js settings
254 250 # This URL must use SSL in order to keep chat sessions secure
255 251 CONVERSEJS_BOSH_SERVICE_URL = SITE_URL + '/http-bind'
256 252  
257 253 CONVERSEJS_AUTO_REGISTER = 'mensageiro.interlegis.gov.br'
258 254  
  255 +
259 256 try:
260 257 from local_settings import *
261 258 except ImportError:
... ...
src/colab/local_settings-dev.py
... ... @@ -9,15 +9,32 @@ ADMINS = (
9 9  
10 10 MANAGERS = ADMINS
11 11  
12   -SOLR_COLAB_URI = None
13   -SOLR_HOSTNAME = None
  12 +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
  13 +#EMAIL_HOST = ''
  14 +#EMAIL_PORT = 587
  15 +EMAIL_SUBJECT_PREFIX = ''
14 16  
15 17 # Make this unique, and don't share it with anybody.
16 18 SECRET_KEY = ')(jksdfhsjkadfhjkh234ns!8fqu-1186h$vuj'
17 19  
18 20 SITE_URL = 'http://localhost:8000'
19 21  
  22 +ALLOWED_HOSTS = ['*']
  23 +
20 24 INTERNAL_IPS = ('127.0.0.1', )
21 25  
22 26 CONVERSEJS_BOSH_SERVICE_URL = 'http://localhost:5280/http-bind'
23 27  
  28 +DATABASES['default']['PASSWORD'] = 'colab'
  29 +DATABASES['default']['HOST'] = 'localhost'
  30 +DATABASES['trac']['PASSWORD'] = 'colab'
  31 +DATABASES['trac']['HOST'] = 'localhost'
  32 +
  33 +HAYSTACK_CONNECTIONS['default']['URL'] = 'http://localhost:8983/solr/'
  34 +
  35 +COLAB_TRAC_URL = 'http://localhost:5000/'
  36 +COLAB_CI_URL = 'http://localhost:8080/ci/'
  37 +
  38 +CONVERSEJS_ENABLED = False
  39 +
  40 +DIAZO_THEME = SITE_URL
... ...
src/planet/templates/feedzilla/index.html
... ... @@ -8,9 +8,11 @@
8 8 <hr>
9 9 {% empty %}
10 10 <h2>{% trans 'There is no RSS registered' %}</h2>
11   - <h3>{% trans 'Please' %}
12   - href="{% url "feedzilla_submit_blog" %}">{% trans 'click here' %}</a>
  11 + <h3>
  12 + {% trans 'Please' %}
  13 + <a href="{% url "feedzilla_submit_blog" %}">{% trans 'click here' %}</a>
13 14 {% trans 'to submit a blog' %}</h3>
  15 + </h3>
14 16 {% endfor %}
15 17  
16 18 {% include "common/pagination.html" %}
... ...
src/proxy/diazo/trac.xml
... ... @@ -14,7 +14,6 @@
14 14 .navbar .nav li { border: 0; padding: 0; white-space: normal; display: list-item;}
15 15 :link:not(.btn),
16 16 :visited:not(.btn) { border: 0; color: rgb(66, 139, 202); }
17   - :link, :visited { border: 0; }
18 17 h1 { font-size: 24px; margin: 0.15em 1em 0.5em 0px; }
19 18 h2 { font-size: 20px }
20 19 h3 { font-size: 16px }
... ...
src/proxy/models.py
... ... @@ -73,7 +73,7 @@ class Wiki(models.Model):
73 73 db_table = 'wiki_view'
74 74  
75 75 def get_absolute_url(self):
76   - return u'/ticket/{}'.format(self.name)
  76 + return u'/wiki/{}'.format(self.name)
77 77  
78 78 def get_author(self):
79 79 try:
... ...
src/super_archives/search_indexes.py
... ... @@ -29,7 +29,7 @@ class ThreadIndex(indexes.SearchIndex, indexes.Indexable):
29 29 return Thread
30 30  
31 31 def get_updated_field(self):
32   - return 'received_time'
  32 + return 'latest_message__received_time'
33 33  
34 34 def prepare_author(self, obj):
35 35 return obj.message_set.first().from_address.get_full_name()
... ...
src/super_archives/templates/message-list.html
1 1 {% extends "base.html" %}
2   -{% load i18n %}
3   -{% load append_to_get %}
  2 +{% load i18n superarchives %}
4 3 {% block main-content %}
5 4 <div>
6 5 <h2>{% trans "Discussions" %}</h2>
... ...
src/super_archives/templatetags/superarchives.py
1 1  
2 2 from django import template
3 3  
  4 +from super_archives.utils import url
  5 +
4 6  
5 7 register = template.Library()
6 8 TEMPLATE_PATH = 'superarchives/tags/'
... ... @@ -12,3 +14,21 @@ def display_message(email):
12 14 email.update_blocks()
13 15  
14 16 return { 'blocks': email.blocks.all }
  17 +
  18 +
  19 +@register.simple_tag(takes_context=True)
  20 +def append_to_get(context, **kwargs):
  21 + return url.append_to_get(
  22 + context['request'].META['PATH_INFO'],
  23 + context['request'].META['QUERY_STRING'],
  24 + **kwargs
  25 + )
  26 +
  27 +
  28 +@register.simple_tag(takes_context=True)
  29 +def pop_from_get(context, **kwargs):
  30 + return url.pop_from_get(
  31 + context['request'].META['PATH_INFO'],
  32 + context['request'].META['QUERY_STRING'],
  33 + **kwargs
  34 + )
... ...
src/super_archives/templatetags/urlutils.py
... ... @@ -1,24 +0,0 @@
1   -# -*- coding: utf-8 -*-
2   -
3   -from django import template
4   -
5   -from super_archives.utils import url
6   -
7   -register = template.Library()
8   -
9   -
10   -@register.simple_tag(takes_context=True)
11   -def append_to_get(context, **kwargs):
12   - return url.append_to_get(
13   - context['request'].META['PATH_INFO'],
14   - context['request'].META['QUERY_STRING'],
15   - **kwargs
16   - )
17   -
18   -@register.simple_tag(takes_context=True)
19   -def pop_from_get(context, **kwargs):
20   - return url.pop_from_get(
21   - context['request'].META['PATH_INFO'],
22   - context['request'].META['QUERY_STRING'],
23   - **kwargs
24   - )
src/super_archives/utils/url.py
1 1 # -*- coding: utf-8 -*-
2 2  
3   -def append_to_get(path, query=None, **kwargs):
4   -# Getting the path with the query
5   - current_url = u'{}?{}'.format(
6   - path,
7   - query,
8   - )
  3 +import urllib
  4 +import urlparse
9 5  
10   - if kwargs and query:
11   - current_url += '&'
12 6  
  7 +def append_to_get(path, query=None, **kwargs):
  8 + query_dict = dict(urlparse.parse_qsl(query))
13 9 for key, value in kwargs.items():
14   - # get the key, value to check if the pair exists in the query
15   - new = u'{}={}'.format(key, value)
16   -
17   - if new in current_url:
18   - continue
19   -
20   - if key not in current_url:
21   - current_url += u'{}={}&'.format(key, value)
22   - continue
23   -
24   - parse_url = current_url.split(key)
25   -
26   - if len(parse_url) > 2:
27   - continue
28   -
29   - if unicode(value) in parse_url[1][1:]:
30   - continue
31   -
32   - check_kwargs_values = [
33   - False for value in kwargs.values()
34   - if unicode(value) not in parse_url[1]
35   - ]
36   -
37   - if not all(check_kwargs_values):
38   - list_remaining = parse_url[1][1:].split('&')
39   - real_remaining = u''
40   -
41   - if len(list_remaining) >= 2:
42   - real_remaining = u'&'.join(list_remaining[1:])
43   -
44   - current_url = u'{url}{key}={value}&{remaining}'.format(
45   - url=parse_url[0],
46   - key=key,
47   - value=value,
48   - remaining=real_remaining,
49   - )
50   - continue
51   -
52   - current_url = u'{url}{key}={value}+{remaining_get}'.format(
53   - url=parse_url[0],
54   - key=key,
55   - value=value,
56   - remaining_get=parse_url[1][1:],
57   - )
58   - if current_url[-1] == '&':
59   - return current_url[:-1]
60   - return current_url
  10 + query_dict[key] = value
  11 + return u'{}?{}'.format(path, urllib.urlencode(query_dict))
61 12  
62 13  
63 14 def pop_from_get(path, query=None, **kwargs):
... ...
src/super_archives/views.py
1 1 # -*- coding: utf-8 -*-
2 2  
3 3 import smtplib
  4 +import logging
4 5  
5 6 from django import http
6 7 from django.conf import settings
... ... @@ -212,6 +213,7 @@ class EmailValidationView(View):
212 213 send_verification_email(email_addr, request.user,
213 214 email.validation_key)
214 215 except smtplib.SMTPException:
  216 + logging.exception('Error sending validation email')
215 217 return http.HttpResponseServerError()
216 218  
217 219 return http.HttpResponse(status=204)
... ...
src/templates/search.html
1 1 {% extends "base.html" %}
2   -{% load i18n %}
3   -{% load append_to_get %}
  2 +{% load i18n superarchives %}
  3 +
4 4 {% block main-content %}
5 5 <div class="row">
6 6 <div class="col-lg-2">
... ...
src/templates/search/search.html
1 1 {% extends "base.html" %}
2   -{% load i18n %}
3   -{% load urlutils %}
4   -{% load highlight %}
  2 +{% load i18n highlight superarchives %}
5 3  
6 4 {% block main-content %}
7 5 <div class="row">
... ... @@ -72,7 +70,7 @@
72 70 {% endfor %}
73 71 </ul>
74 72  
75   - {% if query and page.has_other_pages %}
  73 + {% if page.has_other_pages %}
76 74 <div class="text-center">
77 75 <span>
78 76 {% if page.has_previous %}
... ...