Browse Source

impl channels tutorial 1 e 2

pull/2585/head
Leandro Roberto 7 years ago
parent
commit
c8b0b78d66
  1. 5
      requirements/requirements.txt
  2. 48
      sapl/base/consumers.py
  3. 7
      sapl/base/routing.py
  4. 5
      sapl/base/urls.py
  5. 81
      sapl/base/views.py
  6. 11
      sapl/routing.py
  7. 18
      sapl/settings.py
  8. 27
      sapl/templates/base/channel_index.html
  9. 47
      sapl/templates/base/channel_room.html
  10. 6
      setup.py

5
requirements/requirements.txt

@ -15,7 +15,6 @@ django-extensions==2.1.4
django-image-cropping==1.2 django-image-cropping==1.2
django-webpack-loader==0.6.0 django-webpack-loader==0.6.0
drf-yasg==1.13.0 drf-yasg==1.13.0
channels==2.1.7
easy-thumbnails==2.5 easy-thumbnails==2.5
python-decouple==3.1 python-decouple==3.1
psycopg2-binary==2.7.6.1 psycopg2-binary==2.7.6.1
@ -34,5 +33,9 @@ whoosh==2.7.4
pyoai==2.5.0 pyoai==2.5.0
daphne==2.2.5
channels_redis==2.3.3
channels==2.1.7
git+git://github.com/interlegis/trml2pdf.git git+git://github.com/interlegis/trml2pdf.git
git+git://github.com/interlegis/django-admin-bootstrapped git+git://github.com/interlegis/django-admin-bootstrapped

48
sapl/base/consumers.py

@ -0,0 +1,48 @@
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
# Receive message from room group
def chat_message(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message
}))

7
sapl/base/routing.py

@ -0,0 +1,7 @@
from django.conf.urls import url
from . import consumers
websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
]

5
sapl/base/urls.py

@ -8,6 +8,7 @@ from django.contrib.auth.views import (password_reset, password_reset_complete,
password_reset_done) password_reset_done)
from django.views.generic.base import RedirectView, TemplateView from django.views.generic.base import RedirectView, TemplateView
from sapl import base
from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud
from sapl.settings import EMAIL_SEND_USER, MEDIA_URL from sapl.settings import EMAIL_SEND_USER, MEDIA_URL
@ -185,4 +186,8 @@ urlpatterns = [
LogotipoView.as_view(), name='logotipo'), LogotipoView.as_view(), name='logotipo'),
url(r'^channel$', base.views.chanel_index, name='channel_index'),
url(r'^channel/(?P<room_name>[^/]+)/$',
base.views.chanel_room, name='channel_room'),
] + recuperar_senha + alterar_senha + admin_user ] + recuperar_senha + alterar_senha + admin_user

81
sapl/base/views.py

@ -1,6 +1,7 @@
import collections import collections
import itertools
import datetime import datetime
import itertools
import json
import logging import logging
import os import os
@ -15,11 +16,13 @@ from django.core.urlresolvers import reverse, reverse_lazy
from django.db import connection from django.db import connection
from django.db.models import Count, Q, ProtectedError from django.db.models import Count, Q, ProtectedError
from django.http import Http404, HttpResponseRedirect from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render
from django.template import TemplateDoesNotExist from django.template import TemplateDoesNotExist
from django.template.loader import get_template from django.template.loader import get_template
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.safestring import mark_safe
from django.utils.translation import string_concat from django.utils.translation import string_concat
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import (CreateView, DeleteView, FormView, ListView, from django.views.generic import (CreateView, DeleteView, FormView, ListView,
@ -61,6 +64,16 @@ from .forms import (AlterarSenhaForm, CasaLegislativaForm,
from .models import AppConfig, CasaLegislativa from .models import AppConfig, CasaLegislativa
def chanel_index(request):
return render(request, 'base/channel_index.html', {})
def chanel_room(request, room_name):
return render(request, 'base/channel_room.html', {
'room_name_json': mark_safe(json.dumps(room_name))
})
def filtra_url_materias_em_tramitacao(qr, qs, campo_url, local_ou_status): def filtra_url_materias_em_tramitacao(qr, qs, campo_url, local_ou_status):
id_materias = [] id_materias = []
filtro_url = qr[campo_url] filtro_url = qr[campo_url]
@ -289,7 +302,7 @@ class AutorCrud(CrudAux):
class RelatoriosListView(TemplateView): class RelatoriosListView(TemplateView):
template_name='base/relatorios_list.html' template_name = 'base/relatorios_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(TemplateView, self).get_context_data(**kwargs) context = super(TemplateView, self).get_context_data(**kwargs)
@ -799,8 +812,8 @@ class RelatorioNormasPublicadasMesView(FilterView):
context['ano'] = self.request.GET['ano'] context['ano'] = self.request.GET['ano']
normas_mes = collections.OrderedDict() normas_mes = collections.OrderedDict()
meses = {1: 'Janeiro', 2: 'Fevereiro', 3:'Março', 4: 'Abril', 5: 'Maio', 6:'Junho', 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'} 7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'}
for norma in context['object_list']: for norma in context['object_list']:
if not meses[norma.data.month] in normas_mes: if not meses[norma.data.month] in normas_mes:
normas_mes[meses[norma.data.month]] = [] normas_mes[meses[norma.data.month]] = []
@ -836,16 +849,17 @@ class RelatorioNormasVigenciaView(FilterView):
if vigencia == 'True': if vigencia == 'True':
qs_dt_not_null = qs.filter(data_vigencia__isnull=True) qs_dt_not_null = qs.filter(data_vigencia__isnull=True)
qs = (qs_dt_not_null | qs.filter(data_vigencia__gte=datetime.datetime.now().date())).distinct() qs = (qs_dt_not_null | qs.filter(
data_vigencia__gte=datetime.datetime.now().date())).distinct()
else: else:
qs = qs.filter(data_vigencia__lt=datetime.datetime.now().date()) qs = qs.filter(
data_vigencia__lt=datetime.datetime.now().date())
kwargs.update({ kwargs.update({
'queryset': qs 'queryset': qs
}) })
return kwargs return kwargs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(RelatorioNormasVigenciaView, context = super(RelatorioNormasVigenciaView,
self).get_context_data(**kwargs) self).get_context_data(**kwargs)
@ -855,17 +869,20 @@ class RelatorioNormasVigenciaView(FilterView):
if not self.filterset.form.is_valid(): if not self.filterset.form.is_valid():
return context return context
normas_totais = NormaJuridica.objects.filter(ano=self.request.GET['ano']) normas_totais = NormaJuridica.objects.filter(
ano=self.request.GET['ano'])
context['quant_total'] = len(normas_totais) context['quant_total'] = len(normas_totais)
if self.request.GET['vigencia'] == 'True': if self.request.GET['vigencia'] == 'True':
context['vigencia'] = 'Vigente' context['vigencia'] = 'Vigente'
context['quant_vigente'] = len(context['object_list']) context['quant_vigente'] = len(context['object_list'])
context['quant_nao_vigente'] = context['quant_total'] - context['quant_vigente'] context['quant_nao_vigente'] = context['quant_total'] - \
context['quant_vigente']
else: else:
context['vigencia'] = 'Não vigente' context['vigencia'] = 'Não vigente'
context['quant_nao_vigente'] = len(context['object_list']) context['quant_nao_vigente'] = len(context['object_list'])
context['quant_vigente'] = context['quant_total'] - context['quant_nao_vigente'] context['quant_vigente'] = context['quant_total'] - \
context['quant_nao_vigente']
qr = self.request.GET.copy() qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
@ -904,8 +921,8 @@ class EstatisticasAcessoNormas(TemplateView):
rows = cursor.fetchall() rows = cursor.fetchall()
normas_mes = collections.OrderedDict() normas_mes = collections.OrderedDict()
meses = {1: 'Janeiro', 2: 'Fevereiro', 3:'Março', 4: 'Abril', 5: 'Maio', 6:'Junho', 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'} 7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'}
for row in rows: for row in rows:
if not meses[int(row[2])] in normas_mes: if not meses[int(row[2])] in normas_mes:
@ -915,7 +932,8 @@ class EstatisticasAcessoNormas(TemplateView):
# Ordena por acesso e limita em 5 # Ordena por acesso e limita em 5
for n in normas_mes: for n in normas_mes:
sorted_by_value = sorted(normas_mes[n], key=lambda kv: kv[1], reverse=True) sorted_by_value = sorted(
normas_mes[n], key=lambda kv: kv[1], reverse=True)
normas_mes[n] = sorted_by_value[0:5] normas_mes[n] = sorted_by_value[0:5]
context['normas_mes'] = normas_mes context['normas_mes'] = normas_mes
@ -952,8 +970,8 @@ class ListarInconsistenciasView(PermissionRequiredMixin, ListView):
tabela.append( tabela.append(
('mandato_sem_data_inicio', ('mandato_sem_data_inicio',
'Mandatos sem data inicial', 'Mandatos sem data inicial',
len(mandato_sem_data_inicio()) len(mandato_sem_data_inicio())
) )
) )
tabela.append( tabela.append(
('parlamentares_mandatos_intersecao', ('parlamentares_mandatos_intersecao',
@ -977,7 +995,7 @@ class ListarInconsistenciasView(PermissionRequiredMixin, ListView):
('legislatura_infindavel', ('legislatura_infindavel',
'Legislaturas sem data fim', 'Legislaturas sem data fim',
len(legislatura_infindavel()) len(legislatura_infindavel())
) )
) )
return tabela return tabela
@ -1000,14 +1018,14 @@ class ListarLegislaturaInfindavelView(PermissionRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super( context = super(
ListarLegislaturaInfindavelView, self ListarLegislaturaInfindavelView, self
).get_context_data(**kwargs) ).get_context_data(**kwargs)
paginator = context['paginator'] paginator = context['paginator']
page_obj = context['page_obj'] page_obj = context['page_obj']
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.' ] = 'Nenhuma encontrada.'
return context return context
@ -1050,14 +1068,14 @@ class ListarBancadaComissaoAutorExternoView(PermissionRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super( context = super(
ListarBancadaComissaoAutorExternoView, self ListarBancadaComissaoAutorExternoView, self
).get_context_data(**kwargs) ).get_context_data(**kwargs)
paginator = context['paginator'] paginator = context['paginator']
page_obj = context['page_obj'] page_obj = context['page_obj']
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.' ] = 'Nenhum encontrado.'
return context return context
@ -1084,7 +1102,7 @@ class ListarAutoresDuplicadosView(PermissionRequiredMixin, ListView):
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.' ] = 'Nenhum encontrado.'
return context return context
@ -1097,10 +1115,12 @@ def parlamentares_mandatos_intersecao():
for c in combinacoes: for c in combinacoes:
data_inicio_mandato1 = c[0].data_inicio_mandato data_inicio_mandato1 = c[0].data_inicio_mandato
data_fim_mandato1 = c[0].data_fim_mandato if c[0].data_fim_mandato else timezone.now().date() data_fim_mandato1 = c[0].data_fim_mandato if c[0].data_fim_mandato else timezone.now(
).date()
data_inicio_mandato2 = c[1].data_inicio_mandato data_inicio_mandato2 = c[1].data_inicio_mandato
data_fim_mandato2 = c[1].data_fim_mandato if c[1].data_fim_mandato else timezone.now().date() data_fim_mandato2 = c[1].data_fim_mandato if c[1].data_fim_mandato else timezone.now(
).date()
if data_inicio_mandato1 and data_inicio_mandato2: if data_inicio_mandato1 and data_inicio_mandato2:
exists = intervalos_tem_intersecao( exists = intervalos_tem_intersecao(
@ -1131,7 +1151,7 @@ class ListarParlMandatosIntersecaoView(PermissionRequiredMixin, ListView):
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.' ] = 'Nenhum encontrado.'
return context return context
@ -1152,14 +1172,14 @@ class ListarMandatoSemDataInicioView(PermissionRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super( context = super(
ListarMandatoSemDataInicioView, self ListarMandatoSemDataInicioView, self
).get_context_data(**kwargs) ).get_context_data(**kwargs)
paginator = context['paginator'] paginator = context['paginator']
page_obj = context['page_obj'] page_obj = context['page_obj']
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrada.' ] = 'Nenhum encontrada.'
return context return context
@ -1187,14 +1207,14 @@ class ListarMatProtocoloInexistenteView(PermissionRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super( context = super(
ListarMatProtocoloInexistenteView, self ListarMatProtocoloInexistenteView, self
).get_context_data(**kwargs) ).get_context_data(**kwargs)
paginator = context['paginator'] paginator = context['paginator']
page_obj = context['page_obj'] page_obj = context['page_obj']
context['page_range'] = make_pagination( context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhuma encontrada.' ] = 'Nenhuma encontrada.'
return context return context
@ -1230,7 +1250,7 @@ class ListarProtocolosComMateriasView(PermissionRequiredMixin, ListView):
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.' ] = 'Nenhum encontrado.'
return context return context
@ -1244,6 +1264,7 @@ def protocolos_duplicados():
return [(v[0], len(v)) for (k, v) in protocolos.items() if len(v) > 1] return [(v[0], len(v)) for (k, v) in protocolos.items() if len(v) > 1]
class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView): class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView):
model = get_user_model() model = get_user_model()
template_name = 'base/protocolos_duplicados.html' template_name = 'base/protocolos_duplicados.html'
@ -1263,7 +1284,7 @@ class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView):
page_obj.number, paginator.num_pages) page_obj.number, paginator.num_pages)
context[ context[
'NO_ENTRIES_MSG' 'NO_ENTRIES_MSG'
] = 'Nenhum encontrado.' ] = 'Nenhum encontrado.'
return context return context

11
sapl/routing.py

@ -1,5 +1,12 @@
from channels.routing import ProtocolTypeRouter from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import sapl.base.routing
application = ProtocolTypeRouter({ application = ProtocolTypeRouter({
# Empty for now (http->django views is added by default) 'websocket': AuthMiddlewareStack(
URLRouter(
sapl.base.routing.websocket_urlpatterns
)
),
}) })

18
sapl/settings.py

@ -207,6 +207,14 @@ TEMPLATES = [
WSGI_APPLICATION = 'sapl.wsgi.application' WSGI_APPLICATION = 'sapl.wsgi.application'
ASGI_APPLICATION = "sapl.routing.application" ASGI_APPLICATION = "sapl.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
# Database # Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
@ -347,11 +355,11 @@ LOGGING = {
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,
}, },
'django': { #'django': {
'handlers': ['applogfile'], # 'handlers': ['applogfile'],
'level': 'ERROR', # 'level': 'ERROR',
'propagate': True, # 'propagate': True,
}, #},
} }
} }

27
sapl/templates/base/channel_index.html

@ -0,0 +1,27 @@
<!-- chat/templates/chat/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Rooms</title>
</head>
<body>
What chat room would you like to enter?<br/>
<input id="room-name-input" type="text" size="100"/><br/>
<input id="room-name-submit" type="button" value="Enter"/>
<script>
document.querySelector('#room-name-input').focus();
document.querySelector('#room-name-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#room-name-submit').click();
}
};
document.querySelector('#room-name-submit').onclick = function(e) {
var roomName = document.querySelector('#room-name-input').value;
window.location.pathname = '/channel/' + roomName + '/';
};
</script>
</body>
</html>

47
sapl/templates/base/channel_room.html

@ -0,0 +1,47 @@
<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
<textarea id="chat-log" cols="100" rows="20"></textarea><br/>
<input id="chat-message-input" type="text" size="100"/><br/>
<input id="chat-message-submit" type="button" value="Send"/>
</body>
<script>
var roomName = {{ room_name_json }};
var chatSocket = new WebSocket(
'ws://' + window.location.host +
'/ws/chat/' + roomName + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
document.querySelector('#chat-log').value += (message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
var messageInputDom = document.querySelector('#chat-message-input');
var message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
</script>
</html>

6
setup.py

@ -44,13 +44,7 @@ install_requires = [
'channels==2.1.7', 'channels==2.1.7',
# 'git+git://github.com/interlegis/trml2pdf.git', # 'git+git://github.com/interlegis/trml2pdf.git',
<<<<<<< HEAD
# 'git+git://github.com/interlegis/django-admin-bootstrapped', # 'git+git://github.com/interlegis/django-admin-bootstrapped',
=======
# 'git+git://github.com/jasperlittle/django-rest-framework-docs',
# 'git+git://github.com/interlegis/django-admin-bootstrapped',
>>>>>>> config inicial
] ]
setup( setup(
name='interlegis-sapl', name='interlegis-sapl',

Loading…
Cancel
Save