Created
April 1, 2020 23:06
-
-
Save osw4l/af4a61e5a3d28b930ea076a53cbe4137 to your computer and use it in GitHub Desktop.
ws channels v1 example <3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from channels import Group | |
from channels.auth import channel_session_user_from_http | |
from channels.sessions import channel_session | |
from apps.calls.models import Contacto | |
@channel_session_user_from_http | |
def connect_update_contacto(message, pk): | |
contacto = Contacto.objects.get(id=pk) | |
if not contacto.editor: | |
contacto.activo = True | |
contacto.save() | |
message.reply_channel.send({"accept": True}) | |
Group("contacto_{}".format(contacto.id)).add(message.reply_channel) | |
@channel_session_user_from_http | |
def disconnect_update_contacto(message, pk): | |
contacto = Contacto.objects.get(id=pk) | |
contacto.activo = False | |
contacto.save() | |
Group("contacto_{}".format(pk)).discard(message.reply_channel) | |
def connect_contactos_user(message): | |
message.reply_channel.send({'accept': True}) | |
Group("pending_calls_{}".format(message.user.id)).add(message.reply_channel) | |
def disconnect_contactos_user(message): | |
Group("pending_calls_{}".format(message.user.id)).discard(message.reply_channel) | |
def connect_pending_calls(message): | |
print(message) | |
message.reply_channel.send({'accept': True}, True) | |
Group("pending_calls").add(message.reply_channel) | |
def disconnect_pending_calls(message): | |
Group("pending_calls").discard(message.reply_channel) | |
def connect_count_pending(message): | |
message.reply_channel.send({'accept': True}) | |
Group("pending_for_call").add(message.reply_channel) | |
def disconnect_count_pending(message): | |
Group("pending_for_call").discard(message.reply_channel) | |
def connect_pending_calls_user_counter(message, pk): | |
message.reply_channel.send({'accept': True}) | |
Group("pending_for_call_counter_{}".format(pk)).add(message.reply_channel) | |
def disconnect_pending_calls_user_counter(message, pk): | |
Group("pending_for_call_counter_{}".format(pk)).discard(message.reply_channel) | |
def connect_pending_calls_user(message, pk): | |
message.reply_channel.send({'accept': True}) | |
Group("pending_for_call_{}".format(pk)).add(message.reply_channel) | |
def disconnect_pending_calls_user(message, pk): | |
Group("pending_for_call_{}".format(pk)).discard(message.reply_channel) | |
def connect_remove_call(message, pk): | |
message.reply_channel.send({'accept': True}) | |
Group("remove_call_{}".format(pk)).add(message.reply_channel) | |
def disconnect_remove_call(message, pk): | |
Group("remove_call_{}".format(pk)).discard(message.reply_channel) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
from channels import Group | |
class Contacto(models.Model): | |
creado_por = models.ForeignKey( | |
'auth.User', | |
on_delete=models.CASCADE, | |
related_name='+', | |
blank=True | |
) | |
cedula = models.CharField( | |
unique=True, | |
max_length=15, | |
blank=True, | |
null=True | |
) | |
celular = models.CharField( | |
max_length=12 | |
) | |
red_social = models.ForeignKey( | |
RedSocial, | |
on_delete=models.CASCADE, | |
blank=True, | |
null=True | |
) | |
fecha_creacion = models.DateField( | |
auto_now_add=True | |
) | |
hora_creacion = models.TimeField( | |
auto_now_add=True | |
) | |
fecha_actualizacion = models.DateField( | |
auto_now=True | |
) | |
hora_actualizacion = models.TimeField( | |
auto_now=True | |
) | |
asignado = models.BooleanField( | |
default=False | |
) | |
asignacion = models.DateTimeField( | |
blank=True, | |
null=True | |
) | |
activo = models.BooleanField( | |
default=False | |
) | |
no_volver_a_llamar = models.BooleanField( | |
default=False | |
) | |
voto_fuerte = models.BooleanField( | |
default=False | |
) | |
# asignacion | |
asignado_a = models.ForeignKey( | |
'auth.User', | |
on_delete=models.CASCADE, | |
blank=True, | |
null=True, | |
related_name='+', | |
) | |
asignado_por = models.ForeignKey( | |
'auth.User', | |
on_delete=models.CASCADE, | |
blank=True, | |
null=True, | |
related_name='+', | |
) | |
motivo = models.TextField( | |
blank=True, | |
null=True | |
) | |
# datos del formulario parte 1 | |
nombre = models.CharField( | |
max_length=100 | |
) | |
apellidos = models.CharField( | |
max_length=100 | |
) | |
email = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
municipio = models.ForeignKey( | |
'geo.Municipio', | |
on_delete=models.CASCADE | |
) | |
corregimiento = models.ForeignKey( | |
'geo.Corregimiento', | |
on_delete=models.CASCADE, | |
blank=True, | |
null=True | |
) | |
direccion = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
barrio = models.CharField( | |
max_length=50, | |
blank=True, | |
null=True | |
) | |
fecha_nacimiento = models.DateField( | |
blank=True, | |
null=True, | |
default=datetime.datetime.now().date() | |
) | |
genero = models.CharField( | |
max_length=20, | |
choices=( | |
('Masculino', 'Masculino'), | |
('Femenino', 'Femenino'), | |
('Otro', 'Otro') | |
), | |
blank=True, | |
null=True | |
) | |
edad = models.PositiveIntegerField( | |
blank=True, | |
null=True | |
) | |
tipo_de_votante = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
candidato_1 = models.BooleanField( | |
default=False | |
) | |
candidato_2 = models.BooleanField( | |
default=False | |
) | |
# datos segunda pestaña | |
nivel_formacion = models.CharField( | |
max_length=40, | |
blank=True, | |
null=True | |
) | |
tipo_material_publicitario = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
tipo_aporte = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
cantidad_aportada = models.CharField( | |
max_length=100, | |
blank=True, | |
null=True | |
) | |
# booleanos | |
referidos_fuera_residencia = models.BooleanField( | |
default=False | |
) | |
reuniones = models.BooleanField( | |
default=False | |
) | |
distribuir_material = models.BooleanField( | |
default=False | |
) | |
capacitacion_voluntarios = models.BooleanField( | |
default=False | |
) | |
procesamiento_db = models.BooleanField( | |
default=False | |
) | |
aportes_economicos = models.BooleanField( | |
default=False | |
) | |
volanteo = models.BooleanField( | |
default=False | |
) | |
sondeos_opinion = models.BooleanField( | |
default=False | |
) | |
participacion_hechos_politicos = models.BooleanField( | |
default=False | |
) | |
apoyos_redes_sociales = models.BooleanField( | |
default=False | |
) | |
donacion_material_publicitario = models.BooleanField( | |
default=False | |
) | |
prestamo_vehiculo = models.BooleanField( | |
default=False | |
) | |
visitas_puerta_puerta = models.BooleanField( | |
default=False | |
) | |
divulgacion_propuestas = models.BooleanField( | |
default=False | |
) | |
alojamiento_voluntarios = models.BooleanField( | |
default=False | |
) | |
coordinar_logistica_eventos = models.BooleanField( | |
default=False | |
) | |
aportes_en_especie = models.BooleanField( | |
default=False | |
) | |
movilizar_avanzada = models.BooleanField( | |
default=False | |
) | |
llamadas = models.PositiveIntegerField( | |
default=0 | |
) | |
evento = models.ForeignKey( | |
Evento, | |
on_delete=models.CASCADE, | |
blank=True, | |
null=True | |
) | |
instrucciones = models.TextField( | |
blank=True, | |
null=True | |
) | |
class Meta: | |
verbose_name = 'Contacto' | |
verbose_name_plural = 'Contactos' | |
def get_historial_llamadas(self): | |
return RegistroLLamada.objects.filter( | |
contacto=self | |
).order_by('-fecha', '-hora') | |
def get_llamadas(self): | |
return self.get_historial_llamadas().count() | |
def get_promedio(self): | |
count = self.get_historial_llamadas().count() | |
result = 0 | |
if count > 0: | |
calls = sum([ | |
c.calificacion for c in self.get_historial_llamadas() | |
]) | |
result = calls / count | |
return result | |
def get_full_name(self): | |
return '{} {}'.format( | |
self.nombre, | |
self.apellidos | |
) | |
def get_notification_data(self): | |
return { | |
'id': self.id, | |
'nombre_completo': '{}'.format( | |
self.get_full_name() | |
), | |
'fecha_creacion': self.fecha_creacion.strftime('%Y-%m-%d'), | |
'celular': self.celular, | |
'nombre_municipio': self.municipio.nombre, | |
'activo': self.activo, | |
'asignado_a': { | |
'id': self.asignado_a.id, | |
'name': self.asignado_a.get_full_name() | |
} if self.asignado_a is not None else None, | |
'motivo': self.motivo, | |
'asignado': self.asignado, | |
'asignado_por': self.asignado_por.id if self.asignado_por else None, | |
'user': self.creado_por.id, | |
'nombre_red_social': self.red_social.nombre if self.red_social else '', | |
'calls': self.llamadas | |
} | |
def send_notification(self): | |
if self.asignado_a: | |
Group('pending_calls_{}'.format( | |
self.asignado_a.id | |
)).send({ | |
"text": json.dumps(self.get_notification_data()) | |
}, True) | |
@classmethod | |
def asignacion_masiva(cls, kwargs, **query): | |
datos = cls.objects.filter(**query)[:kwargs['registros']] | |
for dato in datos: | |
dato.asignado_a_id = kwargs['usuario'] | |
dato.asignado = True | |
dato.asignado_por = kwargs['request_user'] | |
dato.asignacion = datetime.datetime.now() | |
dato.instrucciones = kwargs['instrucciones'] | |
dato.evento_id = kwargs['evento'] | |
dato.save() | |
Group("pending_for_call_counter_{}".format(kwargs['usuario'])).send({ | |
"text": json.dumps({ | |
"items": datos.count() | |
}) | |
}) | |
def send_notification_remove(self): | |
Group("remove_call_{}".format(self.asignado_a.id)).send({ | |
"text": json.dumps({ | |
"id": self.id | |
}) | |
}) | |
def liberar(self): | |
if self.asignado_a: | |
self.send_notification_remove() | |
self.llamadas += 1 | |
self.asignado_a = None | |
self.asignado = False | |
self.asignado_por = None | |
self.asignacion = None | |
self.motivo = None | |
self.evento = None | |
self.save( | |
update_fields=[ | |
'asignado_a', | |
'asignado', | |
'asignado_por', | |
'asignacion', | |
'motivo', | |
'evento', | |
'llamadas' | |
] | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from channels import route | |
from apps.calls import consumer | |
channel_routing = [ | |
route('websocket.connect', | |
consumer.connect_update_contacto, | |
path=r'^/ws/contacto/(?P<pk>\d+)/'), | |
route('websocket.disconnect', | |
consumer.disconnect_update_contacto, | |
path=r'^/ws/contacto/(?P<pk>\d+)/'), | |
route('websocket.connect', | |
consumer.connect_contactos_user, | |
path=r'^/ws/contactos_user/'), | |
route('websocket.disconnect', | |
consumer.disconnect_contactos_user, | |
path=r'^/ws/contactos_user/'), | |
route('websocket.connect', | |
consumer.connect_pending_calls, | |
path=r'^/ws/contactos/'), | |
route('websocket.disconnect', | |
consumer.disconnect_pending_calls, | |
path=r'^/ws/contactos/'), | |
route('websocket.connect', | |
consumer.connect_pending_calls_user, | |
path=r'^/ws/llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.disconnect', | |
consumer.disconnect_pending_calls_user, | |
path=r'^/ws/llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.connect', | |
consumer.connect_pending_calls_user, | |
path=r'^/ws/llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.disconnect', | |
consumer.disconnect_pending_calls_user, | |
path=r'^/ws/llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.connect', | |
consumer.connect_pending_calls_user_counter, | |
path=r'^/ws/contador_llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.disconnect', | |
consumer.disconnect_pending_calls_user_counter, | |
path=r'^/ws/contador_llamadas_pendientes/(?P<pk>\d+)/'), | |
route('websocket.connect', | |
consumer.connect_remove_call, | |
path=r'^/ws/remove_call/(?P<pk>\d+)/'), | |
route('websocket.disconnect', | |
consumer.disconnect_remove_call, | |
path=r'^/ws/remove_call/(?P<pk>\d+)/'), | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment