def send_voter_sms(voter_id, tpl, override_mobile=None, resend=False, dry=True): voter = Voter.objects.select_related().get(pk=voter_id) if not voter.voter_mobile and not override_mobile: raise Exception("Voter mobile field not set") dlr_url = settings.SECURE_URL_HOST + reverse( 'election_poll_sms_delivery', args=(voter.poll.election.uuid, voter.poll.uuid)) client = mobile.get_client(voter.poll.election.uuid, dlr_url=dlr_url) message = "" context = Context({ 'voter': voter, 'poll': voter.poll, 'election': voter.poll.election, 'reg_code': voter.voter_login_id, 'login_code': voter.login_code, 'email': voter.voter_email, 'secret': voter.voter_password, 'SECURE_URL_HOST': settings.SECURE_URL_HOST }) t = Template(tpl) message = t.render(context) # identify and sanitize mobile number voter_mobile = override_mobile or voter.voter_mobile try: voter_mobile = utils.sanitize_mobile_number(voter_mobile) except Exception, e: return False, "Invalid number (%s)" % str(voter_mobile)
def send_voter_sms(voter_id, tpl, override_mobile=None, resend=False, dry=True): voter = Voter.objects.select_related().get(pk=voter_id) if not voter.voter_mobile and not override_mobile: raise Exception("Voter mobile field not set") dlr_url = settings.SECURE_URL_HOST + reverse('election_poll_sms_delivery', args=(voter.poll.election.uuid, voter.poll.uuid)) client = mobile.get_client(voter.poll.election.uuid, dlr_url=dlr_url) message = "" context = Context({ 'voter': voter, 'poll': voter.poll, 'election': voter.poll.election, 'reg_code': voter.voter_login_id, 'login_code': voter.login_code, 'email': voter.voter_email, 'secret': voter.voter_password, 'SECURE_URL_HOST': settings.SECURE_URL_HOST }) t = Template(tpl) message = t.render(context) # identify and sanitize mobile number voter_mobile = override_mobile or voter.voter_mobile try: voter_mobile = utils.sanitize_mobile_number(voter_mobile) except Exception, e: return False, "Invalid number (%s)" % str(voter_mobile)
def handle(self, *args, **options): reload(sys) sys.setdefaultencoding("utf-8") euuid = options.get("election_uuid") puuid = options.get("poll_uuid") voter_id = options.get("voter_id") dry = options.get("dry") list = options.get("list_voters") async = options.get("async") template = options.get("template") send_to_arg = options.get("send_to") resend = options.get("resend") status = options.get("status") voters_voted = options.get("voters_voted") voters_not_voted = options.get("voters_not_voted") mobiles_map_file = options.get("mobiles_map_file") if voters_voted and voters_not_voted: raise CommandError("Please use only one of --voters-voted/--voters-not-voted") if not any([euuid, puuid]): raise CommandError("Please provide election or poll uuid.") if not template: raise CommandError("Please provide a template file.") if not os.path.exists(template): raise CommandError("Template file does not exist.") if dry and not status: print "Running in dry mode. No messages will be send." if mobiles_map_file and not os.path.exists(mobiles_map_file): raise CommandError("Voters mobiles file does not exist.") voters = Voter.objects.filter() all_voters = Voter.objects.filter() tplfd = file(template) tpl = tplfd.read() tplfd.close() election = None if euuid: voters = voters.filter(poll__election__uuid=euuid) election = Election.objects.get(uuid=euuid) if puuid: voters = voters.filter(poll__uuid=puuid) election = Poll.objects.select_related().get(uuid=puuid).election if voter_id: voters = voters.filter(voter_login_id=voter_id) if not status: print "Will send %d messages" % voters.count() mobiles_map = None if mobiles_map_file: mobiles_map = {} with open(mobiles_map_file, "r") as f: data = f.read() reader = utils.CSVReader(data, min_fields=3, max_fields=4) for fields in reader: voter_id = fields[0].strip() email = fields[1].strip() mobile = fields[2].strip() if voter_id in mobiles_map.keys(): raise CommandError(("Duplicate voter id found in mobiles" " csv file: %d") % int(voter_id)) mobiles_map[voter_id] = {"mobile": mobile, "email": email} try: utils.sanitize_mobile_number(mobile) except: raise CommandError("Invalid mobile number: %s (%s)" % (email, mobile)) voters = voters.filter(voter_login_id__in=mobiles_map.keys()) if voters.count() != len(mobiles_map.keys()): for voter_id in mobiles_map.keys(): if not all_voters.filter(voter_login_id=voter_id).count(): raise CommandError("Voter id not found in " "database: %s" % voter_id) for voter in voters: voter_id = voter.voter_login_id email = voter.voter_email csv_email = mobiles_map[voter_id]["email"] if email != csv_email: print repr(email), repr(csv_email) raise CommandError( "Voter email does not match the one" " in database: %s, %s, %s" % (voter_id, email, csv_email) ) if election: print "Using SMS API credentials for user '%s'" % mobile_api.CREDENTIALS_DICT[election.uuid]["username"] for voter in voters: send_to = send_to_arg if list: print voter.voter_email, voter.zeus_string continue task = tasks.send_voter_sms if status: task = tasks.check_sms_status if async: task = task.delay if status: if not voter.last_sms_code: print "No SMS notification for %s" % (voter.zeus_string) continue res = task(voter.pk, voter.last_sms_code, election.uuid) print "%s: %s" % (voter.zeus_string, res) continue self.stdout.write("Sending sms to %s " % (voter.zeus_string)) if not resend and voter.last_sms_send_at: d = voter.last_sms_send_at.strftime("%d/%m/%Y %H:%M:%S") print "Skipping. Already send at %r" % d continue if dry: print if mobiles_map: mapped = mobiles_map.get(voter.voter_login_id) send_to = send_to or (mapped and mapped.get("mobile")) if not voter.voter_mobile and not send_to: print "Skipping. No voter mobile set" continue if send_to: print ("Overriding mobile number. Voter mobile: %s. " "Will use : %s") % ( voter.voter_mobile or "<not-set>", send_to, ) res, error = task(voter.pk, tpl, override_mobile=send_to, resend=resend, dry=dry) if res: if not dry: self.stdout.write(": ") print "[SUCCESS] Message sent successfully (%s)" % error else: if not dry: self.stdout.write(": ") print "[ERROR] Message failed to send (%s)" % error if dry: print
def handle(self, *args, **options): euuid = options.get('election_uuid') puuid = options.get('poll_uuid') voter_id = options.get('voter_id') dry = options.get('dry') list = options.get('list_voters') async = options.get('async') template = options.get('template') send_to_arg = options.get('send_to') resend = options.get('resend') status = options.get('status') voters_voted = options.get('voters_voted') voters_not_voted = options.get('voters_not_voted') mobiles_map_file = options.get('mobiles_map_file') if voters_voted and voters_not_voted: raise CommandError( "Please use only one of --voters-voted/--voters-not-voted") if not any([euuid, puuid]): raise CommandError("Please provide election or poll uuid.") if not template: raise CommandError("Please provide a template file.") if not os.path.exists(template): raise CommandError("Template file does not exist.") if dry and not status: print("Running in dry mode. No messages will be send.") if mobiles_map_file and not os.path.exists(mobiles_map_file): raise CommandError("Voters mobiles file does not exist.") voters = Voter.objects.filter() all_voters = Voter.objects.filter() with open(template) as f: tpl = f.read() election = None if euuid: voters = voters.filter(poll__election__uuid=euuid) election = Election.objects.get(uuid=euuid) if puuid: voters = voters.filter(poll__uuid=puuid) election = Poll.objects.select_related().get(uuid=puuid).election if voters_not_voted: voters = voters.filter(cast_at__isnull=True) if voter_id: voters = voters.filter(voter_login_id=voter_id) if not status: print("Will send %d messages" % voters.count()) mobiles_map = None if mobiles_map_file: mobiles_map = {} with open(mobiles_map_file, 'r') as f: data = f.read() reader = utils.CSVReader(data, min_fields=3, max_fields=4) for fields in reader: voter_id = fields[0].strip() email = fields[1].strip() mobile = fields[2].strip() if voter_id in list(mobiles_map.keys()): raise CommandError(("Duplicate voter id found in mobiles" " csv file: %d") % int(voter_id)) mobiles_map[voter_id] = {'mobile': mobile, 'email': email} try: utils.sanitize_mobile_number(mobile) except Exception: raise CommandError("Invalid mobile number: %s (%s)" % (email, mobile)) voters = voters.filter(voter_login_id__in=list(mobiles_map.keys())) if voters.count() != len(list(mobiles_map.keys())): for voter_id in list(mobiles_map.keys()): if not all_voters.filter(voter_login_id=voter_id).count(): raise CommandError("Voter id not found in " "database: %s" % voter_id) for voter in voters: voter_id = voter.voter_login_id email = voter.voter_email csv_email = mobiles_map[voter_id]['email'] if email != csv_email: print(repr(email), repr(csv_email)) raise CommandError("Voter email does not match the one" " in database: %s, %s, %s" % (voter_id, email, csv_email)) if election: print("Using SMS API credentials for user '%s'" % mobile_api.CREDENTIALS_DICT[election.uuid]['username']) for voter in voters: send_to = send_to_arg if list: print(voter.voter_email, voter.zeus_string.encode('utf8')) continue task = tasks.send_voter_sms if status: task = tasks.check_sms_status if async: task = task.delay if status: if not voter.last_sms_code: print("No SMS notification for %s" % (voter.zeus_string)) continue res = task(voter.pk, voter.last_sms_code, election.uuid) print("%s: %s" % (voter.zeus_string, res)) continue self.stdout.write("Sending sms to %s " % (voter.zeus_string)) if not resend and voter.last_sms_send_at: d = voter.last_sms_send_at.strftime("%d/%m/%Y %H:%M:%S") print("Skipping. Already send at %r" % d) continue if dry: print() if mobiles_map: mapped = mobiles_map.get(voter.voter_login_id) send_to = send_to or (mapped and mapped.get('mobile')) if not voter.voter_mobile and not send_to: print("Skipping. No voter mobile set") continue if send_to: print(("Overriding mobile number. Voter mobile: %s. " "Will use : %s") % (voter.voter_mobile or "<not-set>", send_to)) res, error = task(voter.pk, tpl, override_mobile=send_to, resend=resend, dry=dry) if res: if not dry: self.stdout.write(": ") print("[SUCCESS] Message sent successfully (%s)" % error) else: if not dry: self.stdout.write(": ") print("[ERROR] Message failed to send (%s)" % error) if dry: print()