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 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 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 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 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 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 get_step_strings(self, registration_steps): step_messages = set() registration_script_names = self.get_registration_script_name() for step in registration_steps: if step and step.poll: language = registration_script_names[step.script.slug] step_messages.add(gettext_db(step.poll.question, language)) else: step_messages.add(step.message) return list(step_messages)
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, message): try: progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time') 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 response: message.respond(gettext_db(response,progress.language)) return True except ScriptProgress.DoesNotExist: pass return False
def handle(self, message): try: progress = ScriptProgress.objects.filter( connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time') 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 response: message.respond(gettext_db(response, progress.language)) return True except ScriptProgress.DoesNotExist: pass 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 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): 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