Browse Source

Atualiza com o master

pull/505/head
Eduardo Calil 9 years ago
parent
commit
430a63d282
  1. 7
      requirements/dev-requirements.txt
  2. 26
      requirements/requirements.txt
  3. 10
      requirements/test-requirements.txt
  4. 19
      sapl/base/migrations/0016_auto_20160701_0940.py
  5. 6
      sapl/base/models.py
  6. 2
      sapl/base/templatetags/menus.py
  7. 15
      sapl/base/views.py
  8. 1
      sapl/crispy_layout_mixin.py
  9. 98
      sapl/parlamentares/forms.py
  10. 4
      sapl/templates/parlamentares/layouts.yaml
  11. 33
      sapl/test_crispy_layout_mixin.py
  12. 14
      sapl/test_general.py
  13. 38
      scripts/atualizar_requirements.py

7
requirements/dev-requirements.txt

@ -1,7 +1,8 @@
-r test-requirements.txt
autopep8==1.2.2
autopep8==1.2.4
beautifulsoup4==4.4.1
django-debug-toolbar==1.4
ipdb==0.9.0
pygraphviz==1.3rc2
ipdb==0.10.1
pip-review==0.4
pygraphviz==1.3.1
pytest-ipdb==0.1-prerelease2

26
requirements/requirements.txt

@ -2,25 +2,25 @@ dj-database-url==0.4.1
django-admin-bootstrapped==2.5.7
django-bootstrap3==7.0.1
django-bower==5.1.0
django-braces==1.8.1
django-braces==1.9.0
django-compressor==2.0
django-crispy-forms==1.6.0
django-extensions==1.6.1
django-extra-views==0.7.1
django-extensions==1.6.7
django-extra-views==0.8.0
django-filter==0.13.0
django-floppyforms==1.6.1
django-model-utils==2.4
django-sass-processor==0.3.4
django==1.9.5
django-floppyforms==1.6.2
django-model-utils==2.5
django-sass-processor==0.4.0
django==1.9.7
djangorestframework
easy-thumbnails==2.3
git+git://github.com/interlegis/trml2pdf.git
libsass==0.11.0
psycopg2==2.6.1
libsass==0.11.1
psycopg2==2.6.2
python-decouple==3.0
pytz==2016.3
pytz==2016.4
pyyaml==3.11
rtyaml==0.0.2
rtyaml==0.0.3
unipath==1.1
python-magic==0.4.10
gunicorn==19.4.5
python-magic==0.4.12
gunicorn==19.6.0

10
requirements/test-requirements.txt

@ -1,11 +1,11 @@
-r requirements.txt
coverage==4.0.3
coverage==4.1
django-webtest
flake8==2.5.4
flake8==2.6.2
isort==4.2.5
model_mommy==1.2.6
model-mommy==1.2.6
pep8==1.7.0
pytest==2.7.2
pytest-cov==2.2.1
pytest==2.9.2
pytest-cov==2.3.0
pytest-django==2.9.1
webtest==2.0.21

19
sapl/base/migrations/0016_auto_20160701_0940.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-07-01 12:40
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('base', '0015_problemamigracao_nome_campo'),
]
operations = [
migrations.AlterModelOptions(
name='casalegislativa',
options={'verbose_name': 'Casa Legislativa', 'verbose_name_plural': 'Casa Legislativa'},
),
]

6
sapl/base/models.py

@ -46,7 +46,11 @@ class CasaLegislativa(models.Model):
class Meta:
verbose_name = _('Casa Legislativa')
verbose_name_plural = _('Casas Legislativas')
verbose_name_plural = _('Casa Legislativa')
def __str__(self):
return _('Casa Legislativa de %(municipio)s') % {
'municipio': self.municipio}
class ProblemaMigracao(models.Model):

2
sapl/base/templatetags/menus.py

@ -41,7 +41,7 @@ def subnav(context, path=None):
if path:
yaml_path = path
elif 'subnav_template_name' in context:
yaml_path = context['subnav_template_name']
yaml_path = context['subnav_template_name']
else:
yaml_path = '%s/%s' % (app_template, 'subnav.yaml')

15
sapl/base/views.py

@ -1,7 +1,10 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.views.generic.base import TemplateView
from sapl.crud.base import Crud, CrudBaseMixin, CrudCreateView, CrudUpdateView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudUpdateView,
CrudDetailView)
from sapl.utils import permissao_tb_aux
from .forms import CasaLegislativaForm
@ -33,8 +36,16 @@ class CasaLegislativaCrud(Crud):
permission_required = {'base.change_casalegislativa'}
form_class = CasaLegislativaForm
class DetailView(CrudDetailView):
form_class = CasaLegislativaForm
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(
reverse('sapl.base:casalegislativa_update',
kwargs={'pk': self.kwargs['pk']}))
class HelpView(PermissionRequiredMixin, TemplateView):
class HelpView(TemplateView):
# XXX treat non existing template as a 404!!!!
def get_template_names(self):

1
sapl/crispy_layout_mixin.py

@ -145,7 +145,6 @@ class CrispyLayoutFormMixin:
def read_yaml_from_file(yaml_layout):
# TODO cache this at application level
t = template.loader.get_template(yaml_layout)
rendered = t.render()

98
sapl/parlamentares/forms.py

@ -1,14 +1,13 @@
from datetime import date
from datetime import date, timedelta
from django import forms
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import Q
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from floppyforms.widgets import ClearableFileInput
from sapl.utils import intervalos_tem_intersecao
from .models import (ComposicaoColigacao, Filiacao, Legislatura, Mandato,
Parlamentar)
@ -74,59 +73,60 @@ class ParlamentarCreateForm(ParlamentarForm):
def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao):
# Verifica se data de desfiliacao é anterior a data de filiacao
if data_desfiliacao and data_desfiliacao < data_filiacao:
error_msg = _("A data de desfiliação não pode anterior \
à data de filiação")
return [False, error_msg]
filiacao_atual_id = filiacao.pk
# recupera filiacoes em ordem crescente de data
todas_filiacoes = parlamentar.filiacao_set.all().order_by('data')
filiacoes_id = [parlamentar.pk for parlamentar in todas_filiacoes]
# Novo registro inserido com filiacoes ja existentes
if filiacao_atual_id not in filiacoes_id and len(filiacoes_id) > 0:
ultima_filiacao = todas_filiacoes.last()
# Se ultima filiacao aberta e insercao posterior a esta filiacao
if (not ultima_filiacao.data_desfiliacao and
data_filiacao >= ultima_filiacao.data):
error_msg = _("O parlamentar não pode se filiar \
a novo partido sem antes se \
desfiliar do partido anterior")
return [False, error_msg]
# checa intervalos de interseccao
filiacoes = parlamentar.filiacao_set.order_by('data')
if not filiacoes.exists():
return [True, '']
# data ficticia de desfiliacao
df_desfiliacao = data_desfiliacao if data_desfiliacao else date.today()
# se não puder haver filiação no mesmo dia de desfiliação, basta
# retirar os timedelta abaixo
range_livre_exigido = Q(
data__range=[data_filiacao + timedelta(days=1),
df_desfiliacao - timedelta(days=1)]) | Q(
data_desfiliacao__range=[data_filiacao + timedelta(days=1),
df_desfiliacao - timedelta(days=1)])
filiacao_em_edicao_id = filiacao.pk
error_msg = None
for filiacoes in todas_filiacoes:
# nao comparar o registro com ele mesmo
if filiacoes.id != filiacao_atual_id:
# Se a atualizacao eh para remover a data de desfiliacao
if not data_desfiliacao:
# so permite na ultima data (ou a unica)
if filiacao_atual_id != filiacoes_id[-1]:
error_msg = _("Data de desfiliação do parlamentar não \
pode ser ausente, se existirem datas de \
filiação posteriores")
return [False, error_msg]
else:
data_inicio = filiacoes.data
data_fim = filiacoes.data_desfiliacao
# Se filiacao ainda em aberto, preenche uma desfiliacao
# ficticia para fins de checagem de interseccao
if not data_fim:
data_fim = date.today()
# finalmente verifica intersecao
if intervalos_tem_intersecao(data_inicio, data_fim,
data_filiacao, data_desfiliacao):
error_msg = _("A data de filiação e \
desfiliação não podem estar no intervalo \
de outro período de filiação")
break
# filiação em edição não é a última e está sem data de desfiliação
if not data_desfiliacao and filiacao_em_edicao_id and\
filiacao_em_edicao_id != filiacoes.last().pk:
error_msg = _("Data de desfiliação do parlamentar não pode ser\
ausente, se existirem datas de filiação posteriores.")
# a filiação que está sendo inclusa não tem data de desfiliação mas
# já existe outra sem data de desfiliação
elif not data_desfiliacao and not filiacao_em_edicao_id and\
not filiacoes.last().data_desfiliacao:
error_msg = _("O parlamentar não pode se filiar a novo partido sem\
antes se desfiliar do partido anterior.")
if not error_msg:
# se a filiação é uma edição, a exclui das possibilidades
if filiacao_em_edicao_id:
filiacoes = filiacoes.exclude(pk=filiacao_em_edicao_id)
# testa a intercessão de intervalo com outra filiação
if filiacoes.filter(range_livre_exigido).exists():
error_msg = _("A data de filiação e desfiliação não podem estar\
no intervalo de outro período de filiação.")
if not error_msg:
# passou pelo teste de intervalo mas a data de filiação é maior que
# a ultima que está em aberto
if filiacoes.filter(data_desfiliacao__isnull=True,
data__lte=data_filiacao).exists():
error_msg = _("Não pode haver um registro de filiação com data de \
filiação igual ou superior a data de filiação em aberto.")
if error_msg:
return [False, error_msg]

4
sapl/templates/parlamentares/layouts.yaml

@ -62,7 +62,7 @@ ParlamentarCreate:
- biografia
Filiacao:
{% trans ''Filiações Partidárias '' %}:
{% trans 'Filiações Partidárias' %}:
- partido data data_desfiliacao
Mandato:
@ -89,5 +89,5 @@ SituacaoMilitar:
- descricao
ComposicaoColigacao:
{% trans ''Nome do Partido'' %}:
{% trans 'Nome do Partido' %}:
- partido

33
sapl/test_crispy_layout_mixin.py

@ -1,9 +1,13 @@
from unittest import mock
import rtyaml
from sapl.crispy_layout_mixin import read_layout_from_yaml
def test_read_layout_from_yaml(tmpdir):
contents = '''
stub_content = '''
ModelName:
Cool Legend:
- name:9 place tiny
@ -12,18 +16,17 @@ ModelName:
More data:
- equalA equalB equalC
- highlander '''
file = tmpdir.join('zzz.yaml')
file.write(contents)
expected = [
['Cool Legend',
[('name', 9), ('place', 2), ('tiny', 1)],
[('field', 10), ('nature', 2)],
[('kind', 1), ('date', 3), ('unit', 5), ('status', 3)],
],
['More data',
[('equalA', 4), ('equalB', 4), ('equalC', 4)],
[('highlander', 12)],
],
]
assert read_layout_from_yaml(file.strpath, 'ModelName') == expected
with mock.patch('sapl.crispy_layout_mixin.read_yaml_from_file') as ryff:
ryff.return_value = rtyaml.load(stub_content)
assert read_layout_from_yaml('....', 'ModelName') == [
['Cool Legend',
[('name', 9), ('place', 2), ('tiny', 1)],
[('field', 10), ('nature', 2)],
[('kind', 1), ('date', 3), ('unit', 5), ('status', 3)],
],
['More data',
[('equalA', 4), ('equalB', 4), ('equalC', 4)],
[('highlander', 12)],
],
]

14
sapl/test_general.py

@ -7,21 +7,19 @@ from .settings import SAPL_APPS
pytestmark = pytest.mark.django_db
sapl_appconfs = [apps.get_app_config(n) for n in SAPL_APPS]
sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS]
def test_charfiled_textfield():
def test_charfield_textfield():
for app in sapl_appconfs:
for model in app.get_models():
fields = model._meta.local_fields
for field in fields:
if isinstance(field, (CharField, TextField)):
msg = 'Model = %s || Field = %s - %s - %s' % (
model.__name__,
field.attname,
type(field).__name__,
field.null)
assert not field.null, msg
assert not field.null, 'This %s is null: %s.%s' % (
type(field).__name__,
model.__name__,
field.attname)
def test_str_sanity():

38
scripts/atualizar_requirements.py

@ -0,0 +1,38 @@
#!/usr/bin/env python
# Este script altera os arquivos requirements/*requirements.txt
# atualizando as versões fixadas neles para coincidirem com as do venv.
#
# Rode esse script após atualizar as dependências do venv usando, p. ex.:
# pip-review
#
# Após usá-lo confira sempre o resultado com `git diff` e teste as mudanças
import glob
import re
import subprocess
freeze_output = subprocess.Popen(
'pip freeze', shell=True,
stdout=subprocess.PIPE).stdout.read().decode('ascii')
freeze = freeze_output.strip().split('\n')
freeze = {name.lower(): version
for name, version in [re.split('==+', s) for s in freeze]}
req_files = glob.glob('requirements/*requirements.txt')
requirements = [(f, open(f).read().strip().split('\n'))
for f in req_files]
def novas_linhas(linhas):
for linha in linhas:
split = re.split('==', linha)
if len(split) == 1:
yield split[0]
else:
nome, versao = split
nome = nome.lower()
yield '%s==%s' % (nome, freeze[nome])
for arq, linhas in requirements:
with open(arq, 'w') as f:
f.writelines(l + '\n' for l in novas_linhas(linhas))
Loading…
Cancel
Save