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

[WIP] Meetup rsvp integration #12

Open
wants to merge 2 commits into
base: develop
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
40 changes: 28 additions & 12 deletions src/confluence/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@
import os
import environ

# Celery settings
CELERY_BROKER_URL = 'amqp://guest:guest@localhost//'

#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'django-db'
CELERY_TASK_SERIALIZER = 'json'


root = environ.Path(__file__) - 3 # three folder back (/a/b/c/ - 3 = /)
env = environ.Env(DEBUG=(bool, False),) # set default values and casting
Expand All @@ -44,9 +35,6 @@
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')

# FACEBOOK PAGE ACCESS TOKEN
FACEBOOK_PAGE_ACCESS_TOKEN = env('FACEBOOK_PAGE_ACCESS_TOKEN')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', default=True)

Expand Down Expand Up @@ -151,3 +139,31 @@
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'


# Application specific secrets goes here

# Celery settings
CELERY_BROKER_URL = 'amqp://guest:guest@localhost//'

#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'django-db'
CELERY_TASK_SERIALIZER = 'json'

# Registration App specific settings
EXPLARA_API_KEY = env('EXPLARA_API_KEY')
EXPLARA_ATTENDEE_LIST_URL = 'https://www.explara.com/api/e/attendee-list'

## Meetup
MEETUP_API_KEY = env('MEETUP_API_KEY')
MEETUP_RSVP_URL = 'https://api.meetup.com/2/rsvps'


# Social Media App specific settings

# Access token for Facebook page
FACEBOOK_PAGE_ACCESS_TOKEN = env('FACEBOOK_PAGE_ACCESS_TOKEN')


75 changes: 75 additions & 0 deletions src/registration/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""Contains celery tasks to migrate conference attendees from different
ticketing platforms."""

from __future__ import absolute_import, unicode_literals

from django.db.models import Max
from celery import shared_task

from .models import User
from .utils import call_explara_and_fetch_data, process_explara_data_and_populate_db
from .utils import call_meetup_and_fetch_data, process_meetup_data_and_populate_db

@shared_task(name='registration.tasks.sync_database_with_explara')
def sync_database_with_explara(EXPLARA_EVENT_ID):
"""Syncs all new conference attendees from explara with the
application's database.

Args:
- EXPLARA_EVENT_ID: str. Event ID for the explara event.

Returns:
- None
"""

# For having multiple paginated calls to Explara till all the data is
# synced with the database
while True:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please use separate branch and use reference from explara integration PR to get this done?

max_ticket_id = User.objects.all().aggregate(Max('ticket_id'))["ticket_id__max"]

if not max_ticket_id:
max_ticket_id = 0

data = call_explara_and_fetch_data(EXPLARA_EVENT_ID, max_ticket_id)

if data["status"] != 'success':
print("Error from explara: ")
print(data)
break

if not data["attendee"]:
print("No attendees left now")
break

attendee_order_list = data['attendee']

process_explara_data_and_populate_db(attendee_order_list)


@shared_task(name='registration.tasks.rsvp_from_meetup')
def get_rsvp_from_meetup(MEETUP_EVENT_ID):
"""
Gets the rsvp list from meetup.com for a particular event.

Reference meetup doc :
- https://www.meetup.com/meetup_api/docs/2/rsvps/

Args:
- MEETUP_EVENT_ID : str. Event id of the group's event.

Returns:
- None
"""

# The event id is hardcoded for now.
# The api doc says events are paginated

data = call_meetup_and_fetch_data(MEETUP_EVENT_ID)

if data["status"] != "success":
print("Could not fetch data from meetup")
print(data)

meetup_rsvp_list = data["results"]

process_meetup_data_and_populate_db(meetup_rsvp_list)
150 changes: 150 additions & 0 deletions src/registration/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import requests

from confluence.settings import EXPLARA_API_KEY, EXPLARA_ATTENDEE_LIST_URL
from confluence.settings import MEETUP_API_KEY, MEETUP_RSVP_URL
from .models import User


def call_explara_and_fetch_data(EXPLARA_EVENT_ID, max_ticket_id):
"""Syncs all new conference attendees from Explara with the
application's database.

Args:
- EXPLARA_EVENT_ID: str. Event ID for the Explara event.
- max_ticket_id: int. ticket_id till which Explara data is already
synced with the db.

Returns:
- Attendees data: dict. Response in JSON format as fetched from Explara.
"""
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': "Bearer %s" % EXPLARA_API_KEY
}

payload = {
'eventId': EXPLARA_EVENT_ID,
'fromRecord': int(max_ticket_id),
'toRecord': int(max_ticket_id) + 50
}

response = requests.post(
EXPLARA_ATTENDEE_LIST_URL,
data=payload,
headers=headers
)

return response.json()


def process_explara_data_and_populate_db(attendee_order_list):
"""Syncs all new conference attendees from explara with the
application's database.

Args:
- attendee_order_list: list. Attendees list as fetched from Explara's API.

Returns:
- None.
"""
for order in attendee_order_list:
tickets = order['attendee']
for ticket in tickets:
print(ticket)
try:
name, email = ticket['name'], ticket['email']
ticket_no = ticket['ticketNo']
name_list = name.split(' ')
first_name, last_name = name_list[0], name_list[-1]
username = 'explara' + str(ticket_no)
tshirt_size = ticket['details']['T-shirt size']
contact_no = ticket['details']['Contact Number']
if len(contact_no) > 10:
contact_no = contact_no[1:]
except KeyError as e:
print("Error in decoding data")
print(e)
continue

# username is intentionally kept as ticket_no so there
# aren't any chances of DB integrity error of failing UNIQUE
# constraint on username
try:
User.objects.create(
username=username,
first_name=first_name,
last_name=last_name,
email=email,
ticket_id=ticket_no,
tshirt_size=tshirt_size,
contact=contact_no
)
except Exception as e:
print("Cannot create User because: " + str(e))
print("Ticket details for failed user creation entry: ")
print(ticket)
continue


def call_meetup_and_fetch_data(MEETUP_EVENT_ID):
"""
GETs all the meetup rsvp's for a particular event.

Args:
- MEETUP_EVENT_ID: str. Event ID for the Explara event.

Returns:
- meetup_rsvp_list data: dict. Response in JSON format as fetched from Meetup.
"""
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': "Bearer %s" % MEETUP_API_KEY
}

payload = {
'event_id': MEETUP_EVENT_ID,
'rsvp' : 'yes'
}

response = requests.post(
MEETUP_RSVP_URL,
data=payload,
headers=headers
)

return response.json()


def process_meetup_data_and_populate_db(meetup_rsvp_list):
"""
Syncs the rsvp list with meetup

Args:
- meetup_rscp_list : list.

Returns:
- None
"""

for rsvp in meetup_rsvp_list:
members = rsvp['member']
for member in members:
try:
member_id, member_name = member['member_id'], member_name
name_list = member_name.split(' ')
first_name, last_name = name_list[0], name_list[-1]
except KeyError as e:
print("Error decoding data")
print(e)
continue
try:
User.objects.create(
member_id=member_id,
first_name=first_name,
last_name=last_name
)
except Exception as e:
print("Cannot create User %s because: ", member_name)
print(str(e))
continue