diff --git a/meetup_ballot/ballot.py b/meetup_ballot/ballot.py index 388a494..ef8155a 100644 --- a/meetup_ballot/ballot.py +++ b/meetup_ballot/ballot.py @@ -6,6 +6,7 @@ import logging import os import time +import csv from meetup_ballot.meetup import MeetupClient @@ -14,7 +15,7 @@ MAX_RSVPS_VAR = "MAX_RSVPS" RSVP_BEFORE_DAYS = "RSVP_BEFORE_DAYS" NUM_OF_REQUESTS_TO_SLEEP_AFTER = 2 - +NAME_EXCEPTIONS_CSV = "NAME_EXCEPTIONS_CSV" def setup_logging(): """ @@ -88,7 +89,17 @@ def does_member_name_looks_like_spam(member_name): return False -def filter_spam_members(member_ids, client): +def read_name_exceptions(name_exceptions_csv): + """ Read member names from csv files""" + member_ids = [] + with open(name_exceptions_csv) as name_exceptions: + reader = csv.reader(name_exceptions, delimiter=',') + for row in reader: + member_ids.append(int(row[0])) + return member_ids + + +def filter_spam_members(member_ids, client, name_exceptions_csv): """ Returns a list of good member_ids by filtering the spam members :param member_ids: @@ -96,6 +107,7 @@ def filter_spam_members(member_ids, client): :return: """ good_members = [] + name_exceptions = read_name_exceptions(name_exceptions_csv) for i, member_id in enumerate(member_ids): if i % NUM_OF_REQUESTS_TO_SLEEP_AFTER == 0: time.sleep(1) @@ -112,13 +124,19 @@ def filter_spam_members(member_ids, client): ) good_members.append(member_id) else: - logging.info( - "Bad Member name: {} (ID: {})".format(member_name, member_id) - ) + if member_id in name_exceptions: + logging.info( + "Good member name (is in name_exceptions): {} (ID: {})".format(member_name, member_id) + ) + good_members.append(member_id) + else: + logging.info( + "Bad member name: {} (ID: {})".format(member_name, member_id) + ) return good_members -def run_ballot(meetup_key, meetup_urlname): +def run_ballot(meetup_key, meetup_urlname, name_exceptions_csv): """ Run's the PyData London Meetups's RSVP Ballot. :param meetup_key: Meetup.com API Key @@ -140,7 +158,7 @@ def run_ballot(meetup_key, meetup_urlname): member_ids = client.get_member_ids_from_rsvps(event_rsvps) logging.info("Filtering spam members") - good_member_ids = filter_spam_members(member_ids, client) + good_member_ids = filter_spam_members(member_ids, client, name_exceptions_csv) logging.info("Getting event hosts and coorganizers") coorg_hosts_member_ids = client.get_coorganizers_and_hosts_from_rsvps( @@ -178,6 +196,7 @@ def main(): meetup_key = get_environment_variable(MEETUP_KEY_VAR) meetup_urlname = get_environment_variable(MEETUP_URLNAME_VAR) rsvp_before_days = int(get_environment_variable(RSVP_BEFORE_DAYS)) + name_exceptions_csv = get_environment_variable(NAME_EXCEPTIONS_CSV) if check_meetup_is_in_less_than_delta_time( meetup_key, meetup_urlname, days=rsvp_before_days ): @@ -186,7 +205,7 @@ def main(): ) logging.info("Running the PyData London Meetup's RSVP Ballot") try: - run_ballot(meetup_key, meetup_urlname) + run_ballot(meetup_key, meetup_urlname, name_exceptions_csv) except Exception as e: logging.exception(e) else: diff --git a/name_exceptions.csv b/name_exceptions.csv new file mode 100644 index 0000000..7ccc784 --- /dev/null +++ b/name_exceptions.csv @@ -0,0 +1 @@ +5, ExceptionMemberName diff --git a/tests/test_ballot.py b/tests/test_ballot.py index c4fa2f6..b986f3b 100644 --- a/tests/test_ballot.py +++ b/tests/test_ballot.py @@ -8,7 +8,8 @@ def test_member_name(): None, 'Word', 'A BC', - 'Uncle Bob' + 'Uncle Bob', + 'ExceptionMemberName' ] actual = [ballot.does_member_name_looks_like_spam(name) @@ -18,7 +19,8 @@ def test_member_name(): True, True, True, - False + False, + True ] eq_(expected, actual) @@ -29,16 +31,17 @@ def test_filter_spam_members(_): None, 'Word', 'A BC', - 'Uncle Bob' + 'Uncle Bob', + 'ExceptionMemberName' ] mocked_client = MagicMock( get_member_name=MagicMock( side_effect=names ) ) - actual = ballot.filter_spam_members([1, 2, 3, 4], mocked_client) + actual = ballot.filter_spam_members([1, 2, 3, 4, 5], mocked_client, 'name_exceptions.csv') - eq_([4], actual) + eq_([4, 5], actual) @patch('meetup_ballot.ballot.filter_spam_members') @@ -57,7 +60,7 @@ def test_run_ballet(mocked_client_cls, mocked_env, mocked_spam): mocked_env.return_value = 101 mocked_spam.return_value = ['a', 'b', 'c'] - actual_attending_number = ballot.run_ballot('key', 'url') + actual_attending_number = ballot.run_ballot('key', 'url', 'name_exceptions.csv') eq_(2, actual_attending_number)