from datetime import date from functools import wraps from unicodedata import normalize as unicodedata_normalize import hashlib import logging from django import forms from django.apps import apps from django.conf import settings from django.contrib import admin from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied, ValidationError from django.utils.translation import ugettext_lazy as _ from floppyforms import ClearableFileInput import magic from sapl.settings import BASE_DIR sapl_logger = logging.getLogger(BASE_DIR.name) def normalize(txt): return unicodedata_normalize( 'NFKD', txt).encode('ASCII', 'ignore').decode('ASCII') def get_settings_auth_user_model(): return getattr(settings, 'AUTH_USER_MODEL', 'auth.User') autor_label = '''
Autor: {% if form.autor.value %} {{form.autor.value}} {% endif %}
''' autor_modal = ''' ''' class ImageThumbnailFileInput(ClearableFileInput): template_name = 'floppyforms/image_thumbnail.html' class RangeWidgetOverride(forms.MultiWidget): def __init__(self, attrs=None): widgets = (forms.DateInput(format='%d/%m/%Y', attrs={'class': 'dateinput', 'placeholder': 'Inicial'}), forms.DateInput(format='%d/%m/%Y', attrs={'class': 'dateinput', 'placeholder': 'Final'})) super(RangeWidgetOverride, self).__init__(widgets, attrs) def decompress(self, value): if value: return [value.start, value.stop] return [None, None] def format_output(self, rendered_widgets): html = '
%s
%s
'\ % tuple(rendered_widgets) return '
%s
' % html def register_all_models_in_admin(module_name): appname = module_name.split('.') appname = appname[1] if appname[0] == 'sapl' else appname[0] app = apps.get_app_config(appname) for model in app.get_models(): class CustomModelAdmin(admin.ModelAdmin): list_display = [f.name for f in model._meta.fields if f.name != 'id'] if not admin.site.is_registered(model): admin.site.register(model, CustomModelAdmin) def xstr(s): return '' if s is None else str(s) def get_client_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip def get_base_url(request): # TODO substituir por Site.objects.get_current().domain # from django.contrib.sites.models import Site current_domain = request.get_host() protocol = 'https' if request.is_secure() else 'http' return "{0}://{1}".format(protocol, current_domain) def create_barcode(value): ''' creates a base64 encoded barcode PNG image ''' from base64 import b64encode from reportlab.graphics.barcode import createBarcodeDrawing barcode = createBarcodeDrawing('Code128', value=value, barWidth=170, height=50, fontSize=2, humanReadable=True) data = b64encode(barcode.asString('png')) return data.decode('utf-8') YES_NO_CHOICES = [(True, _('Sim')), (False, _('Não'))] TURNO_TRAMITACAO_CHOICES = [ ('P', _('Primeiro')), ('S', _('Segundo')), ('U', _('Único')), ('L', _('Suplementar')), ('F', _('Final')), ('A', _('Votação única em Regime de Urgência')), ('B', _('1ª Votação')), ('C', _('2ª e 3ª Votação')), ] INDICADOR_AFASTAMENTO = [ ('A', _('Afastamento')), ('F', _('Fim de Mandato')), ] def listify(function): @wraps(function) def f(*args, **kwargs): return list(function(*args, **kwargs)) return f UF = [ ('AC', 'Acre'), ('AL', 'Alagoas'), ('AP', 'Amapá'), ('AM', 'Amazonas'), ('BA', 'Bahia'), ('CE', 'Ceará'), ('DF', 'Distrito Federal'), ('ES', 'Espírito Santo'), ('GO', 'Goiás'), ('MA', 'Maranhão'), ('MT', 'Mato Grosso'), ('MS', 'Mato Grosso do Sul'), ('MG', 'Minas Gerais'), ('PR', 'Paraná'), ('PB', 'Paraíba'), ('PA', 'Pará'), ('PE', 'Pernambuco'), ('PI', 'Piauí'), ('RJ', 'Rio de Janeiro'), ('RN', 'Rio Grande do Norte'), ('RS', 'Rio Grande do Sul'), ('RO', 'Rondônia'), ('RR', 'Roraima'), ('SC', 'Santa Catarina'), ('SE', 'Sergipe'), ('SP', 'São Paulo'), ('TO', 'Tocantins'), ('EX', 'Exterior'), ] RANGE_ANOS = [(year, year) for year in range(date.today().year, 1889, -1)] RANGE_MESES = [ (1, 'Janeiro'), (2, 'Fevereiro'), (3, 'Março'), (4, 'Abril'), (5, 'Maio'), (6, 'Junho'), (7, 'Julho'), (8, 'Agosto'), (9, 'Setembro'), (10, 'Outubro'), (11, 'Novembro'), (12, 'Dezembro'), ] RANGE_DIAS_MES = [(n, n) for n in range(1, 32)] TIPOS_TEXTO_PERMITIDOS = ( 'application/vnd.oasis.opendocument.text', 'application/x-vnd.oasis.opendocument.text', 'application/pdf', 'application/x-pdf', 'application/acrobat', 'applications/vnd.pdf', 'text/pdf', 'text/x-pdf', 'text/plain', 'application/txt', 'browser/internal', 'text/anytext', 'widetext/plain', 'widetext/paragraph', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/xml', 'text/xml', 'text/html', ) TIPOS_IMG_PERMITIDOS = ( 'image/jpeg', 'image/jpg', 'image/jpe_', 'image/pjpeg', 'image/vnd.swiftview-jpeg', 'application/jpg', 'application/x-jpg', 'image/pjpeg', 'image/pipeg', 'image/vnd.swiftview-jpeg', 'image/x-xbitmap', 'image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/png', 'application/png', 'application/x-png', ) def fabrica_validador_de_tipos_de_arquivo(lista, nome): def restringe_tipos_de_arquivo(value): mime = magic.from_buffer(value.read(), mime=True) if mime not in lista: raise ValidationError(_('Tipo de arquivo não suportado')) # o nome é importante para as migrations restringe_tipos_de_arquivo.__name__ = nome return restringe_tipos_de_arquivo restringe_tipos_de_arquivo_txt = fabrica_validador_de_tipos_de_arquivo( TIPOS_TEXTO_PERMITIDOS, 'restringe_tipos_de_arquivo_txt') restringe_tipos_de_arquivo_img = fabrica_validador_de_tipos_de_arquivo( TIPOS_IMG_PERMITIDOS, 'restringe_tipos_de_arquivo_img') def intervalos_tem_intersecao(a_inicio, a_fim, b_inicio, b_fim): maior_inicio = max(a_inicio, b_inicio) menor_fim = min(a_fim, b_fim) return maior_inicio <= menor_fim def permissoes(nome_grupo, app_label): lista_permissoes = [] try: perms = list(Permission.objects.filter( group__name=nome_grupo)) for p in perms: lista_permissoes.append('%s.%s' % (app_label, p.codename)) except: pass return set(lista_permissoes) def permission_required_for_app(app_label, login_url=None, raise_exception=False): """ Decorator for views that checks whether a user has a particular permission enabled, redirecting to the log-in page if necessary. If the raise_exception parameter is given the PermissionDenied exception is raised. """ def check_perms(user): if user.has_module_perms(app_label): return True # In case the 403 handler should be called raise the exception if raise_exception: raise PermissionDenied # As the last resort, show the login form return False return user_passes_test(check_perms, login_url=login_url) def permissoes_materia(): return permissoes('Operador de Matéria', 'materia') def permissoes_comissoes(): return permissoes('Operador de Comissões', 'comissoes') def permissoes_norma(): return permissoes('Operador de Norma Jurídica', 'norma') def permissoes_protocoloadm(): return permissoes('Operador de Protocolo Administrativo', 'protocoloadm') def permissoes_adm(): return permissoes('Operador Administrativo', 'protocoloadm') def permissoes_sessao(): return permissoes('Operador de Sessão Plenária', 'sessao') def permissoes_painel(): return permissoes('Operador de Painel Eletrônico', 'painel') def permissoes_autor(): return permissoes('Autor', 'materia') def permissoes_parlamentares(): lista_permissoes = [] try: cts = ContentType.objects.filter(app_label='parlamentares') perms_parlamentares = list(Permission.objects.filter( content_type__in=cts)) for p in perms_parlamentares: lista_permissoes.append('parlamentares.' + p.codename) except: pass return set(lista_permissoes) def permissao_tb_aux(self): u = self.request.user if u.groups.filter(name='Operador Geral').exists() or u.is_superuser: return True else: return False def gerar_hash_arquivo(arquivo, pk, block_size=2**20): md5 = hashlib.md5() arq = open(arquivo, 'rb') while True: data = arq.read(block_size) if not data: break md5.update(data) return 'P' + md5.hexdigest() + '/' + pk