Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize volunteer sms #977

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ mysite.log
venv
.idea/*
media/
logs/*
13 changes: 13 additions & 0 deletions floodrelief/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ def get_list(text):
'simple': {
'format': '%(levelname)s %(message)s'
},
'command': {
'format': '%(asctime)s %(message)s'
},
},
'handlers': {
'file': {
Expand All @@ -188,6 +191,12 @@ def get_list(text):
'filename': 'mysite.log',
'formatter': 'verbose'
},
'send_volunteer_sms': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'logs/send_volunteer_sms.log',
'formatter': 'command'
},
},
'loggers': {
'django': {
Expand All @@ -199,6 +208,10 @@ def get_list(text):
'handlers': ['file'],
'level': 'DEBUG',
},
'send_volunteer_sms': {
'handlers': ['send_volunteer_sms'],
'level': 'DEBUG',
},
}
}

Expand Down
107 changes: 107 additions & 0 deletions mainapp/management/commands/sendvolunteersms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os

from django.core.management.base import BaseCommand
from django.core.cache import cache
import requests
from threading import Thread
from datetime import datetime

from django.conf import settings
import csv
from dateutil import parser
import time

import logging
import calendar


logger = logging.getLogger('send_volunteer_sms')


# python manage.py sendvolunteersms
# python manage.py sendvolunteersms /tmp/volunteer.csv
# python manage.py sendvolunteersms --clearcache=1
class Command(BaseCommand):
# SMS_API_URL = "http://api.esms.kerala.gov.in/fastclient/SMSclient.php"
SMS_API_URL = "http://127.0.0.1:8000/test_send_sms/"
API_USERNAME = os.environ.get("SMS_USER")
API_PASSWORD = os.environ.get("SMS_PASSWORD")

DEFAULT_CSV = os.path.join(settings.BASE_DIR,
'mainapp/management/commands/smsvolunteer.csv')
BATCH_MAX = 10

msg_url_template = "http://keralarescue.in/c/{sendID}/{timestamp}"
message_template = "Thank you for registering to volunteer. Please click here to confirm {url}"
success_check_cache_key = "SendingFailed_{phone}"

def add_arguments(self, parser):
parser.add_argument('path', nargs='?', type=str)
parser.add_argument('--clearcache', nargs='?', type=bool)

@property
def volunteers(self):
with open(self.path, "r") as volunteers:
for volunteer in csv.DictReader(volunteers):
yield volunteer

@staticmethod
def clean_timestamp(timestamp):
# not clear about this logic just copied from -> sms.py
timestamp = parser.parse(timestamp)
timestamp = calendar.timegm(timestamp.utctimetuple())
return str(timestamp)[-4:]

def send_sms(self, payload):
res = requests.get(self.SMS_API_URL, params=payload)
if res.status_code in (200, 201):
cache.set(self.success_check_cache_key.format(
phone=payload["numbers"]), True)
else:
logger.info("failed {} {}".format())

def process_batch(self, batch):
tasks = []
for payload in batch:
self.total_count += 1
t = Thread(target=self.send_sms,
args=(payload,))
tasks.append(t)
t.start()

for task in tasks:
t.join()

def handle(self, *args, **options):
if options["clearcache"]:
logger.info("clearing cache for sendvolunteersms.")
cache.delete_pattern(self.success_check_cache_key.format(phone="*"))
else:
t1 = time.time()
self.path = options["path"] if options["path"] else self.DEFAULT_CSV
batch = []
batch_count = 0
self.total_count = 0
logger.info("STARTING sendvolunteersms.")

for volunteer in self.volunteers:
msg_url = self.msg_url_template.format(sendID=volunteer["ID"],
timestamp="{:%Y-%m-%d %H:%M}".format(datetime.now()))
message = self.message_template.format(url=msg_url)
payload = {'username': self.API_USERNAME,
'password': self.API_PASSWORD,
'message': message,
'numbers': volunteer["phone"]}
if not cache.get(
self.success_check_cache_key.format(
phone=payload["numbers"])):
batch.append(payload)
batch_count += 1
if batch_count == self.BATCH_MAX:
self.process_batch(payload)
batch_count = 0
batch = []
if batch:
self.process_batch(batch)
logger.info("{} COMPLETED IN {} Seconds sendvolunteersms.".format(self.total_count,
time.time() - t1))
170 changes: 170 additions & 0 deletions mainapp/management/commands/smsvolunteer.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
ID,phone
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
1,0123456789
2,9876543210
3,0612345678
2 changes: 2 additions & 0 deletions mainapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@
path('consent_success/', views.ConsentSuccess.as_view(), name='consent_success'),
url(r'c/(?P<pk>\d+)/(?P<ts>\d+)/$', views.VolunteerConsent.as_view(), name='volunteer_consent'),
url('missing_and_finding_persons/', views.ReportFindPerson.as_view(), name='report_find_person'),
url('test_send_sms/', views.test_send_sms, name='test_send_sms'),

]
9 changes: 9 additions & 0 deletions mainapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -941,3 +941,12 @@ class CollectionCenterView(CreateView):
model = CollectionCenter
form_class = CollectionCenterForm
success_url = '/collection_centers/'


def test_send_sms(request):
print(request.GET)
import time
time.sleep(2)
return JsonResponse({
"success": True
}, safe=False)
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ django-storages==1.6.6
python-dateutil
beautifulsoup4==4.6.3
ddtrace==0.12.1
pympler==0.5
django_debug_toolbar==1.9.1