Skip to content

Instantly share code, notes, and snippets.

@osw4l
Created April 1, 2020 23:06
Show Gist options
  • Save osw4l/af4a61e5a3d28b930ea076a53cbe4137 to your computer and use it in GitHub Desktop.
Save osw4l/af4a61e5a3d28b930ea076a53cbe4137 to your computer and use it in GitHub Desktop.
ws channels v1 example <3
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)
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'
]
)
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