def sendSMS(request, facility_pk=0): groups = Group.objects.filter(name__in=['FHD', 'HC', 'Incharge', 'Records Assistant', 'VHT']).order_by('name') facility = HealthFacility.objects.get(pk=facility_pk) if request.method == "GET": return render_to_response("cvs/facility/partials/facility_sendsms.html", {'groups': groups, 'facility': facility}, context_instance=RequestContext(request) ) else: msg = request.POST['msg'] grp = request.POST['group'] if not grp: json = simplejson.dumps({'error': "role is required"}) return HttpResponse(json, mimetype='application/json') if not msg: json = simplejson.dumps({'error': "message is required"}) return HttpResponse(json, mimetype='application/json') reporters = HealthProvider.objects.filter(facility=request.POST['facility'], groups__in=[grp]) recipient_count = reporters.count() conns = Connection.objects.filter(contact__in=reporters) Message.mass_text(msg, conns, status='Q', batch_status='Q') json = simplejson.dumps({'msg': "sent to %s recipients" % recipient_count, 'error': ""}) return HttpResponse(json, mimetype='application/json')
def create_poll(name, type, question, default_response, contacts, user, start_immediately=False): localized_messages = {} bad_conns = Blacklist.objects.values_list('connection__pk', flat=True).distinct() contacts = contacts.exclude(connection__in=bad_conns) poll = Poll.objects.create(name=name, type=type, question=question, default_response=default_response, user=user) for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts: if start_immediately: messages = Message.mass_text(gettext_db(field=question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') else: messages = Message.mass_text(gettext_db(field=question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='L', batch_status='L') poll.messages.add(*messages.values_list('pk', flat=True)) if 'django.contrib.sites' in settings.INSTALLED_APPS: poll.sites.add(Site.objects.get_current()) if start_immediately: poll.start_date = datetime.datetime.now() poll.save() return poll
def perform(self, request, results): if results is None or len(results) == 0: return (_('A message must have one or more recipients!'), _('error')) if request.user and request.user.has_perm('contact.can_message'): text = self.cleaned_data['text'] if isinstance(results[0], Message): connections = results.values_list('connection', flat=True) elif isinstance(results[0], Response): connections = results.values_list('message__connection', flat=True) Message.mass_text( text, Connection.objects.filter(pk__in=connections).distinct(), status='P', batch_status='Q', batch_name=None, priority=10) return ('%d messages sent successfully' % results.count(), 'success') else: return ("You don't have permission to send messages!", 'error')
def broadcast(text): """ Schedule a one-off message for every non-blacklisted connection. """ connections = [ c for c in Connection.objects.all() if not Blacklist.objects.filter(connection=c).exists() ] Message.mass_text(text, connections)
def create_message(self, id, backend, batch=None): fake_connection = Connection(identity=str(id)) fake_connection.backend, created = Backend.objects.get_or_create(name=backend) fake_connection.save() message = Message(status='Q', direction="O") message.connection = fake_connection message.batch = self.batch1 if batch is None else batch message.save() return message
def perform(self, request, results): if type(results).__name__ != 'QuerySet': results = Contact.objects.filter(pk__in=request.REQUEST.get('results', "")) if results is None or len(results) == 0: return 'A message must have one or more recipients!', 'error' if request.user and request.user.has_perm('contact.can_message'): if type(results[0]).__name__ == 'Reporters': con_ids = \ [r.default_connection.split(',')[1] if len(r.default_connection.split(',')) > 1 else 0 for r in results] connections = list(Connection.objects.filter(pk__in=con_ids).distinct()) contacts = list(Contact.objects.filter(pk__in=results.values_list('id', flat=True))) print contacts else: connections = \ list(Connection.objects.filter(contact__pk__in=results.values_list('id', flat=True)).distinct()) contacts = list(results) text = self.cleaned_data.get('text', "") text = text.replace('%', u'\u0025') messages = Message.mass_text(text, connections) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=contacts) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) return 'Message successfully sent to %d numbers' % len(connections), 'success', else: return "You don't have permission to send messages!", 'error',
def start(self): """ This starts the poll: outgoing messages are sent to all the contacts registered with this poll, and the start date is updated accordingly. All incoming messages from these users will be considered as potentially a response to this poll. """ if self.start_date: return contacts = self.contacts localized_messages = {} for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): messages = Message.mass_text( gettext_db(field=self.question, language=language), Connection.objects.filter( contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') #localized_messages[language] = [messages, localized_contacts] self.messages.add(*messages.values_list('pk', flat=True)) self.start_date = datetime.datetime.now() self.save() poll_started.send(sender=self)
def perform(self, request, results): if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('auth.add_message'): connections = \ list(Connection.objects.filter(contact__in=results).distinct()) text = self.cleaned_data.get('text', "") text = text.replace('%', u'\u0025') messages = Message.mass_text(text, connections) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=list(results)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) return ( 'Message successfully sent to %d numbers' % len(connections), 'success', ) else: return ( "You don't have permission to send messages!", 'error', )
def perform(self, request, results): if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('contact.can_message'): connections = \ list(Connection.objects.filter(contact__in=results).distinct()) text = self.cleaned_data.get('text', "") text = text.replace('%', u'\u0025') messages = Message.mass_text(text, connections) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=list(results)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) return ('Message successfully sent to %d numbers' % len(connections), 'success',) else: return ("You don't have permission to send messages!", 'error',)
def perform(self, request, results): if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('contact.can_message'): blacklists = Blacklist.objects.values_list('connection') connections = \ Connection.objects.filter(contact__in=results).exclude(pk__in=blacklists).distinct() text = self.cleaned_data.get('text', "") text = text.replace('%', u'\u0025') if not self.cleaned_data['text_luo'] == '': (translation, created) = \ Translation.objects.get_or_create(language='ach', field=self.cleaned_data['text'], value=self.cleaned_data['text_luo']) messages = Message.mass_text(text, connections) contacts=Contact.objects.filter(pk__in=results) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=list(contacts)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] return ('Message successfully sent to %d numbers' % len(connections), 'success',) else: return ("You don't have permission to send messages!", 'error',)
def start(self): """ This starts the poll: outgoing messages are sent to all the contacts registered with this poll, and the start date is updated accordingly. All incoming messages from these users will be considered as potentially a response to this poll. """ if self.start_date: return contacts = self.contacts localized_messages = {} for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): messages = Message.mass_text(gettext_db(field=self.question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') #localized_messages[language] = [messages, localized_contacts] self.messages.add(*messages.values_list('pk',flat=True)) self.start_date = datetime.datetime.now() self.save() poll_started.send(sender=self)
def mass_text(self): #get one scriptprogress since they are all supposed to be on the same step if self.exists(): prog = self[0] else: return False if prog.step.poll: text = prog.step.poll.question elif prog.step.email: text = prog.step.email else: text = prog.step.message for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_progs = self.filter( Q(language__in=["en", '']) | Q(language=None)) else: localized_progs = self.filter(language=language) if localized_progs.exists(): localized_conns = localized_progs.values_list('connection', flat=True) messages = Message.mass_text( gettext_db(field=text, language=language), Connection.objects.filter( pk__in=localized_conns).distinct(), status='P') return True
def add_to_poll(poll, contacts): localized_messages = {} bad_conns = Blacklist.objects.values_list('connection__pk', flat=True).distinct() contacts = contacts.exclude(connection__in=bad_conns) for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts: messages = Message.mass_text(gettext_db(field=poll.question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') localized_messages[language] = [messages, localized_contacts] # This is the fastest (pretty much only) was to get contacts and messages M2M into the # DB fast enough at scale # cursor = connection.cursor() # for language in localized_messages.keys(): # raw_sql = "insert into poll_poll_contacts (poll_id, contact_id) values %s" % ','.join(\ # ["(%d, %d)" % (poll.pk, c.pk) for c in localized_messages.get(language)[1].iterator()]) # cursor.execute(raw_sql) # # raw_sql = "insert into poll_poll_messages (poll_id, message_id) values %s" % ','.join(\ # ["(%d, %d)" % (poll.pk, m.pk) for m in localized_messages.get(language)[0].iterator()]) # cursor.execute(raw_sql) return poll
def start(self): """ This starts the poll: outgoing messages are sent to all the contacts registered with this poll, and the start date is updated accordingly. All incoming messages from these users will be considered as potentially a response to this poll. """ if self.start_date: return contacts = self.contacts localized_messages = {} for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): messages = Message.mass_text(gettext_db(field=self.question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') localized_messages[language] = [messages, localized_contacts] # This is the fastest (pretty much only) was to get messages M2M into the # DB fast enough at scale cursor = connection.cursor() for language in localized_messages.keys(): raw_sql = "insert into poll_poll_messages (poll_id, message_id) values %s" % ','.join(\ ["(%d, %d)" % (self.pk, m.pk) for m in localized_messages.get(language)[0].iterator()]) cursor.execute(raw_sql) self.start_date = datetime.datetime.now() self.save() poll_started.send(sender=self)
def add_to_poll(poll, contacts): localized_messages = {} bad_conns = Blacklist.objects.values_list('connection__pk', flat=True).distinct() contacts = contacts.exclude(connection__in=bad_conns) for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts: messages = Message.mass_text( gettext_db(field=poll.question, language=language), Connection.objects.filter( contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') localized_messages[language] = [messages, localized_contacts] # This is the fastest (pretty much only) was to get contacts and messages M2M into the # DB fast enough at scale # cursor = connection.cursor() # for language in localized_messages.keys(): # raw_sql = "insert into poll_poll_contacts (poll_id, contact_id) values %s" % ','.join(\ # ["(%d, %d)" % (poll.pk, c.pk) for c in localized_messages.get(language)[1].iterator()]) # cursor.execute(raw_sql) # # raw_sql = "insert into poll_poll_messages (poll_id, message_id) values %s" % ','.join(\ # ["(%d, %d)" % (poll.pk, m.pk) for m in localized_messages.get(language)[0].iterator()]) # cursor.execute(raw_sql) return poll
def perform(self, request, results): if results is None or len(results) == 0: return ("A message must have one or more recipients!", "error") if request.user and request.user.has_perm("contact.can_message"): if type(results[0]).__name__ == "Reporters": con_ids = [ r.default_connection.split(",")[1] if len(r.default_connection.split(",")) > 1 else 0 for r in results ] connections = list(Connection.objects.filter(pk__in=con_ids).distinct()) contacts = list(Contact.objects.filter(pk__in=results.values_list("id", flat=True))) else: connections = list( Connection.objects.filter(contact__pk__in=results.values_list("id", flat=True)).distinct() ) contacts = list(results) text = self.cleaned_data.get("text", "") text = text.replace("%", u"\u0025") messages = Message.mass_text(text, connections) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=contacts) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) return ("Message successfully sent to %d numbers" % len(connections), "success") else: return ("You don't have permission to send messages!", "error")
def mass_text(self): # get one scriptprogress since they are all supposed to be on the same step if self.exists(): prog = self[0] else: return False if prog.step.poll: text = prog.step.poll.question elif prog.step.email: text = prog.step.email else: text = prog.step.message for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_progs = self.filter(Q(language__in=["en", '']) | Q(language=None)) else: localized_progs = self.filter(language=language) if localized_progs.exists(): localized_conns = localized_progs.values_list('connection', flat=True) messages = Message.mass_text(gettext_db(field=text, language=language), Connection.objects.filter(pk__in=localized_conns).distinct(), status='P') return True
def handle(self, message): # We fall to this app when xform fails to match message # Also added here is a special chat group to share messages # between members belonging to the same health facility groups = [] mentions = [] for token in message.text.split(): if token.startswith("#"): groups.append(token[1:]) if token.startswith("@"): mentions.append(token[1:]) groups = [i.lower() for i in groups] mentions = [i.lower() for i in mentions] if 'chat' in groups or 'chat' in mentions: sender = HealthProvider.objects.filter( connection=message.connection) recipients = [] if sender: sender = sender[0] facility = sender.facility if facility: recipients = HealthProvider.objects.filter( facility=sender.facility).exclude( connection__identity=None) recipients = recipients.exclude( connection=sender.default_connection) text = "{0}: {1}".format( sender.default_connection.identity, message.text) sender_text = "sent to {0} members of {1}".format( len(recipients), sender.facility) conns = Connection.objects.filter(contact__in=recipients) if conns: Message.mass_text(text, conns, status='Q', batch_status='Q') message.respond(sender_text) return True if message.connection.contact and not ScriptProgress.objects.filter( connection=message.connection).exists(): if message.connection.contact.healthproviderbase: message.respond( "Thank you for your message. We have forwarded to your DHT for follow-up. If this was meant to be a weekly report, please check and resend." ) return True return False
def perform(self, request, results): from poll.models import gettext_db if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('contact.can_message'): blacklists = Blacklist.objects.values_list('connection') #TODO: Revise for proper internationalization languages = ["fr"] text_fr = self.cleaned_data.get('text_fr', "") text_fr = text_fr.replace('%', u'\u0025') if not self.cleaned_data['text_en'] == '': languages.append('en') (translation, created) = \ Translation.objects.get_or_create(language='en', field=self.cleaned_data['text_fr'], value=self.cleaned_data['text_en']) if not self.cleaned_data['text_ki'] == '': languages.append('ki') (translation, created) = \ Translation.objects.get_or_create(language='ki', field=self.cleaned_data['text_fr'], value=self.cleaned_data['text_ki']) #Everyone gets a message in their language. This behavior may not be ideal #since one may wish to send out a non translated message to everyone regardless of language #TODO: allow sending of non translated message to everyone using a flag total_connections = [] for language in languages: connections = Connection.objects.filter(contact__in=results.filter(language=language)).exclude(pk__in=blacklists).distinct() messages = Message.mass_text(gettext_db(field=text_fr, language=language), connections) contacts = Contact.objects.filter(pk__in=results) total_connections.extend(connections) #Bulk wont work because of a ManyToMany relationship to Contact on MassText #Django API does not allow bulk_create() to work with relation to multiple tables #TODO: Find work around # bulk_list = [ # MassText(user=request.user), # MassText(text=text_fr), # MassText(contacts=list(contacts)) # ] # masstext = MassText.objects.bulk_create(bulk_list) #The bulk_insert manager needs to be updated #TODO: investigate changes made in new Django that are not compatible with BulkInsertManager() # MassText.bulk.bulk_insert(send_pre_save=False, # user=request.user, # text=text_fr, # contacts=list(contacts)) # masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) # masstext = masstexts[0] return ('Message successfully sent to %d numbers' % len(total_connections), 'success',) else: return ("You don't have permission to send messages!", 'error',)
def test_can_send_mass_text_with_batch_name(self): messages_sent = Message.mass_text("MassTestTest-MESSAGE", [self.connection_1, self.connection_2], batch_name="FOO") message_1 = Message.objects.get(pk=messages_sent[0].pk) message_2 = Message.objects.get(pk=messages_sent[1].pk) self.assertEqual(message_1.batch.name, "FOO") self.assertEqual(message_2.batch.name, "FOO")
def sites_postsave_handler(sender, **kwargs): if 'django.contrib.sites' in settings.INSTALLED_APPS: if ((sender == Contact or sender in Contact.__subclasses__()) and kwargs['created']): ContactSite.objects.create(contact=kwargs['instance'], site=Site.objects.get_current()) elif ((sender == User or sender in User.__subclasses__()) and kwargs['created']): UserSite.objects.create(user=kwargs['instance'], site=Site.objects.get_current()) elif ((sender == Group or sender in Group.__subclasses__()) and kwargs['created']): GroupSite.objects.create(group=kwargs['instance'], site=Site.objects.get_current()) # elif (sender == Connection and kwargs['created']): # ConnectionSite.objects.create(connection = kwargs['instance'], site=Site.objects.get_current()) elif ((sender == Message or sender in Message.__subclasses__()) and kwargs['created']): MessageSite.objects.create(message=kwargs['instance'], site=Site.objects.get_current())
def testAddBulk(self): connection2 = Connection.objects.create(backend=self.backend, identity='8675309') connection3 = Connection.objects.create(backend=self.backend, identity='8675310') connection4 = Connection.objects.create(backend=self.backend, identity='8675311') # test that mass texting works with a single number msgs = Message.mass_text('Jenny I got your number', [self.connection]) self.assertEquals(msgs.count(), 1) self.assertEquals(msgs[0].text, 'Jenny I got your number') # test no connections are re-created self.assertEquals(msgs[0].connection.pk, self.connection.pk) msgs = Message.mass_text('Jenny dont change your number', [self.connection, connection2, connection3, connection4], status='L') self.assertEquals(str(msgs.values_list('status', flat=True).distinct()[0]), 'L') self.assertEquals(msgs.count(), 4) # test duplicate connections don't create duplicate messages msgs = Message.mass_text('Turbo King is the greatest!', [self.connection, self.connection]) self.assertEquals(msgs.count(), 1)
def create_poll(name, type, question, default_response, contacts, user,start_immediately=False): localized_messages = {} bad_conns = Blacklist.objects.values_list('connection__pk', flat=True).distinct() contacts=contacts.exclude(connection__in=bad_conns) for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): if start_immediately: messages = Message.mass_text(gettext_db(field=question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') else: messages = Message.mass_text(gettext_db(field=question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='L', batch_status='L') localized_messages[language] = [messages, localized_contacts] poll = Poll.objects.create(name=name, type=type, question=question, default_response=default_response, user=user) # This is the fastest (pretty much only) was to get contacts and messages M2M into the # DB fast enough at scale cursor = connection.cursor() for language in localized_messages.keys(): raw_sql = "insert into poll_poll_contacts (poll_id, contact_id) values %s" % ','.join(\ ["(%d, %d)" % (poll.pk, c.pk) for c in localized_messages.get(language)[1].iterator()]) cursor.execute(raw_sql) raw_sql = "insert into poll_poll_messages (poll_id, message_id) values %s" % ','.join(\ ["(%d, %d)" % (poll.pk, m.pk) for m in localized_messages.get(language)[0].iterator()]) cursor.execute(raw_sql) if 'django.contrib.sites' in settings.INSTALLED_APPS: poll.sites.add(Site.objects.get_current()) if start_immediately: poll.start_date = datetime.datetime.now() poll.save() return poll
def handle(self, **options): text = options.get('text') or 'If you want to stop receiving FREE messages from Mother Reminder please reply with STOP.' outmsgs = ReminderMessage.as_hash().keys() outmsgs.sort() try: lastweek = outmsgs[-1] query = Contact.objects.filter(interested = True).exclude(connection = None) if not options.get('all'): query.filter(last_menses__lt = (datetime.now() - timedelta(weeks=lastweek))) for mother in query: last_optout = Message.objects.filter(connection=mother.default_connection).filter(text=text).order_by('-date') message = Message(connection = mother.default_connection, direction = 'O', status = 'Q', text = text) if not last_optout: message.save() else: if last_optout[0].date + timedelta(weeks=8) <= datetime.now(): message.save() # msg.save() # application, batch, connection, date, direction, flags, id, in_response_to, poll, poll_responses, priority, responses, status, submissions, text except IndexError: pass
def handle(self, message): # We fall to this app when xform fails to match message # Also added here is a special chat group to share messages # between members belonging to the same health facility groups = [] mentions = [] for token in message.text.split(): if token.startswith("#"): groups.append(token[1:]) if token.startswith("@"): mentions.append(token[1:]) groups = [i.lower() for i in groups] mentions = [i.lower() for i in mentions] if 'chat' in groups or 'chat' in mentions: sender = HealthProvider.objects.filter(connection=message.connection) recipients = [] if sender: sender = sender[0] facility = sender.facility if facility: recipients = HealthProvider.objects.filter( facility=sender.facility).exclude(connection__identity=None) recipients = recipients.exclude(connection=sender.default_connection) text = "{0}: {1}".format(sender.default_connection.identity, message.text) sender_text = "sent to {0} members of {1}".format( len(recipients), sender.facility) conns = Connection.objects.filter(contact__in=recipients) if conns: Message.mass_text(text, conns, status='Q', batch_status='Q') message.respond(sender_text) return True if message.connection.contact and not ScriptProgress.objects.filter(connection=message.connection).exists(): if message.connection.contact.healthproviderbase: message.respond("Thank you for your message. We have forwarded to your DHT for follow-up. If this was meant to be a weekly report, please check and resend.") return True return False
def perform(self, request, results): if results is None or len(results) == 0: return ('A message must have one or more recipients!', 'error') if request.user and request.user.has_perm('contact.can_message' ): text = self.cleaned_data['text'] if isinstance(results[0], Message): connections = results.values_list('connection', flat=True) elif isinstance(results[0], Response): connections = results.values_list('message__connection' , flat=True) Message.mass_text(text, Connection.objects.filter(pk__in=connections).distinct(), status='P') return ('%d messages sent successfully' % results.count(), 'success') else: return ("You don't have permission to send messages!", 'error')
def create_message_without_batch(self, id, backend): fake_connection = Connection(identity=str(id)) fake_connection.backend, created = Backend.objects.get_or_create(name=backend) fake_connection.save() message = Message(status='Q', direction="O") message.text = "this is an important message" message.connection = fake_connection message.batch = None message.save() return message
def send_messages_to_contacts(poll): contacts = poll.contacts localized_messages = {} for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): messages = Message.mass_text(gettext_db(field=poll.question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status='Q') #localized_messages[language] = [messages, localized_contacts] poll.messages.add(*messages.values_list('pk', flat=True))
def start(self): """ This starts the poll: outgoing messages are sent to all the contacts registered with this poll, and the start date is updated accordingly. All incoming messages from these users will be considered as potentially a response to this poll. """ self.log_poll_message_info(" TRANSACTION START") if self.start_date: self.log_poll_message_warn(" poll has a start date, not starting poll!") return self.log_poll_message_info(" Saving start date...") self.start_date = datetime.datetime.now() self.save() self.log_poll_message_info(" Start date saved ok.") self.log_poll_message_info(" start - startDate=" + str(self.start_date)) contacts = self.contacts localized_messages = {} self.log_poll_message_info(" checking languages... " + str(dict(settings.LANGUAGES).keys())) for language in dict(settings.LANGUAGES).keys(): if language == "en": """default to English for contacts with no language preference""" localized_contacts = contacts.filter(language__in=["en", '']) else: localized_contacts = contacts.filter(language=language) if localized_contacts.exists(): self.log_poll_message_info(" creating messages using Message.mass_text for [%d] contacts in [%s]..." % ( len(localized_contacts), language)) messages = Message.mass_text(gettext_db(field=self.question, language=language), Connection.objects.filter(contact__in=localized_contacts).distinct(), status='Q', batch_status=self.get_start_poll_batch_status(), batch_name=self.get_outgoing_message_batch_name()) #localized_messages[language] = [messages, localized_contacts] self.log_poll_message_info(" messages created ok. Adding messages to self...") self.messages.add(*messages.values_list('pk', flat=True)) self.log_poll_message_info(" messages added ok.") self.log_poll_message_info(" sending poll_started signal...") poll_started.send(sender=self) self.log_poll_message_info(" poll_started signal sent ok.") self.log_poll_message_info(" TRANSACTION COMMIT")
def test_should_insert_a_classifier_message_for_each_category(self): categories = self.create_dummy_categories() self.load_ibm_seed_data.create_ibm_message_category = self.create_ibm_message_category_mock self.load_ibm_seed_data.create_backend = lambda name: Backend(name=name ) self.load_ibm_seed_data.create_connection = lambda backend, identity: Connection( backend=backend, identity=identity) self.load_ibm_seed_data.create_message = lambda connection, text, direction, status: ( Message(connection=connection, text=text, direction=direction, status=status), True) self.load_ibm_seed_data.create_seed_data(categories) self.assertEquals(self.categories_with_messages_inserted, categories)
def handle(self, **options): connections = options['p'] text = options['t'] user=User.objects.get(pk=int(options['u'])) conns = Connection.objects.filter(pk__in=eval(options['c'][1:-1])).distinct() try: messages = Message.mass_text(text, conns) MassText.bulk.bulk_insert(send_pre_save=False, user=user, text=text, contacts=Contact.objects.filter(reporting_location__pk__in=conns).values_list('pk',flat=True)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) except: pass
def perform(self, request, results): if results is None or len(results) == 0: return (_('A message must have one or more recipients!'), 'error') if request.user and request.user.has_perm('contact.can_message'): blacklists = Blacklist.objects.values_list('connection') connections = \ Connection.objects.filter(contact__in=results).exclude(pk__in=blacklists).distinct() text = self.cleaned_data.get('text', "") text = text.replace('%', u'\u0025') if not self.cleaned_data['text_luo'] == '': (translation, created) = \ Translation.objects.get_or_create(language='ach', field=self.cleaned_data['text'], value=self.cleaned_data['text_luo']) messages = Message.mass_text(text, connections) contacts = Contact.objects.filter(pk__in=results) MassText.bulk.bulk_insert(send_pre_save=False, user=request.user, text=text, contacts=list(contacts)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] return ( _('Message successfully sent to %(connections)d numbers') % { "connections": len(connections) }, 'success', ) else: return ( _("You don't have permission to send messages!"), 'error', )
def handle(self, **options): connections = options['p'] text = options['t'] user = User.objects.get(pk=int(options['u'])) conns = Connection.objects.filter( pk__in=eval(options['c'][1:-1])).distinct() try: messages = Message.mass_text(text, conns) MassText.bulk.bulk_insert( send_pre_save=False, user=user, text=text, contacts=Contact.objects.filter( reporting_location__pk__in=conns).values_list('pk', flat=True)) masstexts = MassText.bulk.bulk_insert_commit(send_post_save=False, autoclobber=True) masstext = masstexts[0] if settings.SITE_ID: masstext.sites.add(Site.objects.get_current()) except: pass
def gen_reminders(self, schedules): for sched in schedules: #get districts for which to generate reminders if sched.extras.recipient_location_type == 'all': districts = Location.objects.filter(type='district') elif sched.extras.recipient_location_type == 'list': districts = Location.objects.filter(type='district', name__in=sched.extras.recipient_location.split(',')) else: districts = Location.objects.filter(type='district', name=sched.extras.recipient_location) my_handler = sched.extras.return_code grps = sched.extras.group_ref.split(',') missing_reports = sched.extras.missing_reports.split(',') expected_reporter = sched.extras.expected_reporter #used to filter out live and training mode users apply_to_all_users = True if sched.extras.allowed_recipients == 'all' else False allowed_recipient_filter = True if sched.extras.allowed_recipients == 'live' else False #for each district get the facilities =>Non reporting for district in districts: print district facilities = HealthFacility.objects.filter(catchment_areas__in=district.\ get_descendants(include_self=True)).select_related('HealthFacilityTypeBase').\ distinct() facilities = facilities.exclude(type__name='dho') total_facilities = facilities.count() reporting_facility_count = 0 non_reporting_facilities = [] stocked_out_facilities = [] for facility in facilities: #print self.get_facility_xform_aggregate(facility,'cases',last_reporting_period(period=19)) #print self.stockout_reporting_vhts(facility,'act',last_reporting_period(period=19),active=False) proposed_recipients = HealthProvider.objects.filter(facility=facility, groups__name__in=grps) if not apply_to_all_users: proposed_recipients = proposed_recipients.filter(active=allowed_recipient_filter) proposed_recipients = proposed_recipients.exclude(connection__identity=None) if not proposed_recipients: continue conns = Connection.objects.filter(contact__in=proposed_recipients) if conns: if not self.facility_has_sent_report(facility, missing_reports, expected_reporter): non_reporting_facilities.append('%s %s' % (facility.name, facility.type.name.upper())) if my_handler == 'non_reporting_facility': args_dict = {'facility':'%s %s' % (facility.name, facility.type.name.upper())} #print sched.message % args_dict reminder_msg = sched.message % args_dict Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q') elif my_handler == '': Message.mass_text(sched.message, conns, status='Q', batch_status='Q') else: reporting_facility_count += 1 #XXX remember to remove active=False if my_handler == 'vht_summary': args_dict = self.non_reporting_vhts(facility, missing_reports, active=allowed_recipient_filter, lp=last_reporting_period(period=0)) if args_dict: args_dict.update({'week':self.last_week}) reminder_msg = sched.message % args_dict #print "#######=>",reminder_msg Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q') elif my_handler == 'vht_aggregate': #here missing_reports serves as args_dict = self.non_reporting_vhts(facility, missing_reports[0], active=False, lp=last_reporting_period(period=0)) args_dict.update({ 'aggregate': self.get_facility_xform_aggregate(facility, missing_reports[0], last_reporting_period(period=0)), 'week': self.last_week }) reminder_msg = sched.message % args_dict Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q') elif my_handler == 'stockouts_facility': self.manage_stock_outs(facility, stocked_out_facilities, last_reporting_period(period=0)) elif my_handler == 'stockouts_vht': args_dict = self.stockout_reporting_vhts(facility, missing_reports[0], last_reporting_period(period=19), active=False) if args_dict['list']: # send reminder args_dict.update({'week':self.last_week}) reminder_msg = sched.message % args_dict Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q') #here we only send to DHTs dhts = HealthProvider.objects.filter(facility__in=facilities, groups__name__in=['DHT']).\ exclude(connection__identity=None).distinct() conns = Connection.objects.filter(contact__in=dhts) if conns: if my_handler == 'dht_summary': args_dict = {'district': district.name, 'total':total_facilities, 'week':self.last_week, 'reporting': reporting_facility_count, 'list': ', '.join(non_reporting_facilities)} reminder_msg = sched.message % args_dict Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q') #print reminder_msg elif my_handler == 'stockouts_facility': if stocked_out_facilities: args_dict = {'stocked_out':len(stocked_out_facilities), 'total': total_facilities, 'list': ', '.join(stocked_out_facilities)} if args_dict['list']: args_dict.update({'week':self.last_week}) reminder_msg = sched.message % args_dict Message.mass_text(reminder_msg, conns, status='Q', batch_status='Q')
def handle (self, message): if handle_dongle_sms(message): return True if message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_OUT_WORDS', ['quit'])]: if Blacklist.objects.filter(connection=message.connection).exists(): message.respond('You cannot send Quit to 6200 (EduTrac) more than once.') return True else: if ScriptProgress.objects.filter(connection=message.connection, script__slug='edtrac_autoreg').exists(): # user is attempting to quit before completing registration message.respond('Your registration is not complete. You cannot quit at this point.') return True Blacklist.objects.create(connection=message.connection) ScriptProgress.objects.filter(connection=message.connection).delete() # delete all script progress since the user has quit ScriptSession.objects.filter(connection=message.connection, end_time=None).delete() # the non closed out sessions need to be expunged as well if (message.connection.contact): message.connection.contact.active = False message.connection.contact.save() message.respond(getattr(settings, 'OPT_OUT_CONFIRMATION', 'Thank you for your contribution to EduTrac. To rejoin the system, send join to 6200')) return True elif message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_IN_WORDS', ['join'])]: if not message.connection.contact: if ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count() == 0: ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\ connection=message.connection) else: message.respond("Your registration is not complete yet, you do not need to 'Join' again.") elif Blacklist.objects.filter(connection=message.connection).exists(): Blacklist.objects.filter(connection=message.connection).delete() if not ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count(): ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\ connection=message.connection) else: message.respond("You are already in the system and do not need to 'Join' again.") return True elif Blacklist.objects.filter(connection=message.connection).count(): return True # when all else fails, quit! else: try: progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time') response_message_string = {"n":"The answer you have provided is not in the correct format. Use figures like 3 to answer the question", "t":"The answer you have provided is not in the correct format. Please follow instructions that were given to you"} if progress.count(): progress = progress[0] script_last_step = ScriptStep.objects.filter(script=progress.script).order_by('-order')[0] if progress.step and progress.step.order == script_last_step.order and progress.status == 'C': return False else: response = incoming_progress(message) if not progress.script.slug == 'edtrac_autoreg': r = Response.objects.filter(contact__connection=message.connection,date__lte=datetime.datetime.now(),message__text=message.text).latest('date') if r is not None: if r.has_errors: progress.status = ScriptProgress.PENDING progress.save() Message.mass_text(response_message_string[r.poll.type], [message.connection]) Message.mass_text(r.poll.question , [message.connection]) if response: message.respond(gettext_db(response,progress.language)) return True except ScriptProgress.DoesNotExist: logger.debug("\nScript Progress object not found for message %s with connection %s" % (message,message.connection)) return False
def handle(self, message): escargot = "mrs_autoreg" match = None matched = None for keywd in settings.KEYWORDS_AND_SLUGS: match = re.match(keywd, message.text, re.IGNORECASE) if match: escargot = settings.KEYWORDS_AND_SLUGS[keywd] matched = message.text[len(match.group(0)) :] # message.text = matched break if escargot == "mrs_opt_out": if not message.connection.contact: # Stop sending you nothing? :-p return False sps = ScriptProgress.objects.filter(connection=message.connection) sps.delete() sps = ScriptSession.objects.filter(connection=message.connection) sps.delete() message.connection.contact.interested = False message.connection.contact.save() # ScriptProgress.objects.create( # script = Script.objects.get(slug = escargot), # connection = message.connection) msg = Message( connection=message.connection, status="Q", direction="O", text="You will no longer receive FREE messages from Mother Reminder. If you want to join again please send JOIN to 6400.", ) msg.save() return False if (not message.connection.contact) or (not ScriptProgress.objects.filter(connection=message.connection)): # if match: if True: # Any word goes for registration. message.connection.contact = Contact.objects.create(name="Anonymous User") message.connection.contact.interested = True message.connection.contact.last_menses = datetime.now() - timedelta(days=42) message.connection.contact.save() message.connection.save() ScriptProgress.objects.create(script=Script.objects.get(slug=escargot), connection=message.connection) else: msg = Message( connection=message.connection, status="Q", direction="O", text="You just contacted Mother Reminder. Did you know that pregnant women should go to the health facility 4 times during preganancy? Stay Healthy!", ) msg.save() return False else: if match and escargot == "mrs_autoreg": msg = Message( connection=message.connection, status="Q", direction="O", text="You are already registered with Mother Reminder and will receive free health info. Reply with STOP to leave Mother Reminder. Re-join by sending JOIN to 6400.", ) msg.save() else: if ScriptProgress.objects.filter(connection=message.connection, step__order=5): msg = Message( connection=message.connection, status="Q", direction="O", text="You just contacted Mother Reminder. Did you know that pregnant women should go to the health facility 4 times during preganancy? Stay Healthy!", ) msg.save() return False
def handle (self, message): if handle_dongle_sms(message): return True if message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_OUT_WORDS', ['quit'])]: if Blacklist.objects.filter(connection=message.connection).exists(): message.respond('You cannot send Quit to 6200 (EduTrac) more than once.') return True else: if ScriptProgress.objects.filter(connection=message.connection, script__slug='edtrac_autoreg').exists(): # user is attempting to quit before completing registration message.respond('Your registration is not complete, you can not quit at this point') return True Blacklist.objects.create(connection=message.connection) ScriptProgress.objects.filter(connection=message.connection).delete() # delete all script progress since the user has quit ScriptSession.objects.filter(connection=message.connection, end_time=None).delete() # the non closed out sessions need to be expunged as well if (message.connection.contact): message.connection.contact.active = False message.connection.contact.save() message.respond(getattr(settings, 'OPT_OUT_CONFIRMATION', 'Thank you for your contribution to EduTrac. To rejoin the system, send join to 6200')) return True elif message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_IN_WORDS', ['join'])]: if not message.connection.contact: if ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count() == 0: ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\ connection=message.connection) else: message.respond("Your registration is not complete yet, you do not need to 'Join' again.") elif Blacklist.objects.filter(connection=message.connection).exists(): Blacklist.objects.filter(connection=message.connection).delete() if not ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count(): ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\ connection=message.connection) else: message.respond("You are already in the system and do not need to 'Join' again.") return True elif Blacklist.objects.filter(connection=message.connection).count(): return True # when all else fails, quit! else: try: progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time') response_message_string = {"n":"The answer you have provided is not in the correct format. Use figures like 3 to answer the question", "t":"The answer you have provided is not in the correct format. Please follow instructions that were given to you"} if progress.count(): progress = progress[0] script_last_step = ScriptStep.objects.filter(script=progress.script).order_by('-order')[0] if progress.step and progress.step.order == script_last_step.order and progress.status == 'C': return False else: response = incoming_progress(message) if not progress.script.slug == 'edtrac_autoreg': r = Response.objects.filter(contact__connection=message.connection,date__lte=datetime.datetime.now(),message__text=message.text).latest('date') if r is not None: if r.has_errors: progress.status = ScriptProgress.PENDING progress.save() Message.mass_text(response_message_string[r.poll.type], [message.connection]) Message.mass_text(r.poll.question , [message.connection]) if response: message.respond(gettext_db(response,progress.language)) return True except ScriptProgress.DoesNotExist: logger.debug("\nScript Progress object not found for message %s with connection %s" % (message,message.connection)) return False
def broadcast(text): """ Schedule a one-off message for every non-blacklisted connection. """ connections = [c for c in Connection.objects.all() if not Blacklist.objects.filter(connection=c).exists()] Message.mass_text(text, connections)
def test_can_send_mass_text_with_no_batch_name(self): messages_sent = Message.mass_text("MassTestTest-MESSAGE", [self.connection_1, self.connection_2]) self.assertEqual(len(messages_sent), 2, "Should have sent 2 messages")