def _main(osm, auth, sections):

    group = Group(osm, auth, MAPPING.keys(), None)

    for section in sections:
        assert section in group.SECTIONIDS.keys(), \
            "section must be in {!r}.".format(group.SECTIONIDS.keys())

    contacts = []

    for section in sections:
        section_contacts = [member2contacts(member, section) for
                          member in group.section_all_members(section)]

        #  flatten list of lists.
        contacts += list(itertools.chain(*section_contacts))

    # Remove blank emails
    contacts = [contact for contact in contacts if contact[2].strip() != "" ]

    # remove duplicates
    by_email = {contact[2]: contact for contact in contacts}
    contacts = list(by_email.values())

    w = csv_writer(sys.stdout)
    w.writerows(contacts)
Exemple #2
0
def _main(osm, auth, sections, outdir, term):

    assert os.path.exists(outdir) and os.path.isdir(outdir)

    group = Group(osm, auth, MAPPING.keys(), term)

    for section in sections:
        assert section in group.SECTIONIDS.keys(), \
            "section must be in {!r}.".format(group.SECTIONIDS.keys())

    for section in sections:
        vcards = [member2vcard(member, section) for
                  member in group.section_all_members(section)]

        open(os.path.join(outdir, section + ".vcf"), 'w').writelines(vcards)
Exemple #3
0
def contacts_detail(osm, auth, sections, csv=False, term=None, no_headers=False):
    group = Group(osm, auth, MAPPING.keys(), term)
    section_map = {'Garrick': 'Beavers',
                   'Paget': 'Beavers',
                   'Swinfen': 'Beavers',
                   'Maclean': 'Cubs',
                   'Somers': 'Cubs',
                   'Rowallan': 'Cubs',
                   'Erasmus': 'Scouts',
                   'Boswell': 'Scouts',
                   'Johnson': 'Scouts'}
    rows = []

    def add_row(section, member):
        rows.append([section_map[section], section, member['first_name'], member['last_name'],
                     member['date_of_birth'],
                     member['contact_primary_1.email1'],
                     member['contact_primary_1.address1'],
                     member['contact_primary_1.address2'],
                     member['contact_primary_1.address3'],
                     member['contact_primary_1.postcode'],
                     member['contact_primary_2.address1'],
                     member['floating.gender'].lower()])

    for section in sections:
        for member in group.section_all_members(section):
            add_row(section, member)

    headers = ["Section", "Section Name", "First", "Last", "DOB", "Email1", "Address1", "Address1.1", "Address1.2", "Address1.3",
               "Address2", "Address3", "Gender"]

    if csv:
        w = csv_writer(sys.stdout)
        if not no_headers:
            w.writerow(list(headers))
        w.writerows(rows)
    else:
        if not no_headers:
            print(tabulate.tabulate(rows, headers=headers))
        else:
            print(tabulate.tabulate(rows, tablefmt="plain"))
def _main(osm, auth, sections, outdir, email, term):

    assert os.path.exists(outdir) and os.path.isdir(outdir)

    group = Group(osm, auth, MAPPING.keys(), term)

    for section in sections:
        assert section in group.SECTIONIDS.keys(), \
            "section must be in {!r}.".format(group.SECTIONIDS.keys())

    vcards = []

    for section in sections:
        section_vcards = [member2vcards(member, section) for
                          member in group.section_all_members(section)]

        #  flatten list of lists.
        vcards += list(itertools.chain(*section_vcards))

    open(os.path.join(outdir, "group.vcf"), 'w').writelines(vcards)

    if email:
        send([email, ], "OSM Group vcards", "".join(vcards))
def sync_contacts(osm, auth, sections, google_accounts,
                  csv=False, term=None, no_headers=False,
                  delete_google_groups=False):
    group = Group(osm, auth, MAPPING.keys(), term)
    section_map = Group.SECTION_TYPE
    contacts = {}

    def get(field, member, section):
        return member["{}.{}".format(section, field)]

    def get_address(func):
        return ",".join([func('address1'),
                         func('address2'),
                         func('address3'),
                         func('postcode')])

    def add_member_contacts(section, section_type, member):
        f1 = functools.partial(get, member=member, section='contact_primary_member')
        custom_field = functools.partial(get, member=member, section='customisable_data')

        first = string.capwords(member['first_name'].strip())
        last_ = string.capwords(member['last_name'].strip())
        last = f'{last_} (OSM)'
        full_name_osm = f'{first} {last}'
        full_name = f'{first} {last}'
        section_capped = string.capwords(section)
        yp_name = string.capwords(f"{first} {last_} ({section_capped} {section_type})")
        parent_groups = [string.capwords(_) for _ in [f'{section} Parents', f'{section_type} Parents',
                                                      f'All Parents', 'All']]
        yl_groups = [string.capwords(_) for _ in
                     [f'{section} Young Leaders', f'{section_type} Young Leaders',
                      f'All Young Leaders', 'All Adults and Young Leaders', 'All']]

        leader_groups = [string.capwords(_) for _ in
                         [f'{section} Leaders', f'{section_type} Leaders',
                          'All Leaders', 'All Adults and Young Leaders',
                          'All']]

        all_adults_and_young_leaders_groups = ['All Adults And Young Leaders', 'All']

        exec_groups = ['Exec Members', 'All']

        def is_valid_email(func, tag):
            email_ = func(tag).strip()
            return (len(email_) != 0
                    and (not email_.startswith('x ') and
                         func("{}_leaders".format(tag)) == "yes"))

        def parse_tel(number_field, default_name):
            index = 0
            for i in range(len(number_field)):
                if number_field[i] not in ['0', '1', '2', '3', '4', '5',
                                           '6', '7', '8', '9', ' ', '\t']:
                    index = i
                    break

            number_ = number_field[:index].strip() if index != 0 else number_field
            name_ = number_field[index:].strip() if index != 0 else default_name

            # print("input = {}, index = {}, number = {}, name = {}".format(
            #    number_field, index, number, name))

            return number_, name_

        # Add member data
        email = f1('email1').strip()
        if group.is_leader(member) and not is_valid_email(f1, 'email1'):
            log.warning(f'{full_name} is a leader but does not have a member email address.')

        if is_valid_email(f1, 'email1'):
            key = '{}-{}-{}'.format(first.lower(), last.lower(), email.lower())
            address = get_address(f1)
            if key not in contacts:
                contacts[key] = dict(first=first,
                                     last=last,
                                     email=email.lower(),
                                     addresses=[],
                                     yp=[],
                                     sections=[],
                                     groups=[],
                                     phones=[])
            contacts[key]['sections'].append(section)
            if not group.is_leader(member):
                contacts[key]['yp'].append(yp_name)

            if section.lower() == 'adult':
                # Everyone in the adult group is either a leader, a non-leader adult or a YL.
                contacts[key]['groups'].extend(all_adults_and_young_leaders_groups)

                if custom_field('cf_exec').lower() in ['y', 'yes']:
                    contacts[key]['groups'].extend(exec_groups)
            else:
                # If we are not in the adult group, we must be in a normal section group
                # so, if they are an adult they must be a leader.
                if group.is_leader(member):
                    contacts[key]['groups'].extend(leader_groups)

            if group.is_yl(member):
                contacts[key]['groups'].extend(yl_groups)
            if len(address):
                contacts[key]['addresses'].append(('member', address))

            for _ in ['phone1', 'phone2']:
                number, name = parse_tel(f1(_), _)
                if number != "":
                    contacts[key]['phones'].append((number, name))

        # For all we add the contact details if they say they want to be contacted
        if not (section.lower() == 'adult' or group.is_leader(member)):
            for _ in ('contact_primary_1', 'contact_primary_2'):
                f = functools.partial(get, member=member, section=_)
                _email = f('email1').strip()
                if is_valid_email(f, 'email1'):

                    _first = f('firstname').strip()
                    _last = f('lastname').strip() if len(f('lastname').strip()) > 0 else last_
                    _last_osm = f'{_last} (OSM)'
                    key = '{}-{}-{}'.format(_first.lower(), _last_osm.lower(), _email.lower())
                    address = get_address(f)
                    if key not in contacts:
                        contacts[key] = dict(first=_first,
                                             last=_last_osm,
                                             email=_email.lower(),
                                             addresses=[],
                                             yp=[],
                                             sections=[],
                                             groups=[],
                                             phones=[])

                    contacts[key]['sections'].append(section)
                    contacts[key]['yp'].append(yp_name)
                    contacts[key]['groups'].extend(parent_groups)
                    if len(address):
                        contacts[key]['addresses'].append((f'{_first} {_last}', address))

                    if group.is_yl(member):
                        contacts[key]['groups'].extend(yl_groups)

                    for _ in ['phone1', 'phone2']:
                        number, name = parse_tel(f(_), _)
                        if number != "":
                            contacts[key]['phones'].append((number, name))

    # For every member in the group we want to extract each unique contact address. We ignore all those that
    # not marked for wanting contact.

    # We then add all of the these unique contacts to google.

    # Now we add each of the contacts to the groups that they are associated with.

    log.info("Fetch members from OSM")
    for section_ in sections:
        for member in group.section_all_members(section_):
            add_member_contacts(section_, Group.SECTION_TYPE[section_], member)

    # for c in contacts.values():
    #    print(f'{c}')

    #  remove duplicates
    groups = []
    for key, contact in contacts.items():
        contact['groups'] = set(contact['groups'])
        contact['sections'] = set(contact['sections'])
        contact['yp'] = set(contact['yp'])
        contact['addresses'] = set(contact['addresses'])
        contact['phones'] = set(contact['phones'])
        groups.extend(contact['groups'])

    #  Gather all the groups
    groups = set(groups)
    group_names = [f"{_} (OSM)" for _ in groups]

    contacts = [contact for key, contact in contacts.items()]

    # Sync up the google groups.

    log.info("Fetch list of groups from google")
    existing_osm_groups = fetch_list_of_groups()

    # Fetch the list of group-members - this is used to find who should
    # be managers of the groups.
    existing_role_group_members = fetch_group_members(
        fetch_list_of_groups(prefix='7th-'))

    if delete_google_groups:
        for group in existing_osm_groups:
            log.info(f"Deleting group: {group}")
            delete_google_group(group)
        existing_osm_groups = fetch_list_of_groups()  # should return empty

    missing_groups = [_ for _ in groups if
                      convert_group_name_to_email_address(_) not in existing_osm_groups]
    if len(missing_groups) > 0:
        create_groups(missing_groups)

    for group in groups:
        group_email_address = convert_group_name_to_email_address(group)
        group_moderators = get_group_moderaters(group_email_address,
                                                existing_role_group_members)
        group_members = [contact for contact in contacts
                         if (group in contact['groups'] and
                             contact['email'] not in group_moderators)]
        if len(group_moderators) == 0:
            log.warning(f'No managers for group: {group_email_address}')

        if len(group_members) == 0:
            log.warning(f'No members in group: {group}')

        log.info(f"Syncing contacts in google group: {group}")
        sync_contacts_in_group(
            group_email_address,
            [_['email'] for _ in group_members])

        sync_contacts_in_group(
            group_email_address, group_moderators, role='manager')

    # Sync all contacts to the global directory.
    log.info("delete OSM contacts in directory")
    delete_osm_contacts_already_in_gam()

    log.info("Create all contacts in directory")
    for contact in contacts:
        create_osm_contact_in_gam(contact)

    for google_account in google_accounts:
        if True:  # Flip this to false to manually remove all contacts from the users.

            log.info(f"Syncing OSM contacts into google account for: {google_account}")
            # Setup and sync all contacts and contact groups to a user.
            existing_groups = fetch_list_of_contact_groups(google_account)
            create_contact_groups([_ for _ in group_names if _ not in existing_groups], google_account)

            delete_osm_contacts_already_in_google(google_account)

            for contact in contacts:
                create_osm_contact_in_google(contact, google_account)

        else:
            # To remove all contacts and contact groups from a user.
            existing_groups = fetch_list_of_contact_groups(google_account, field='ContactGroupID')
            delete_osm_contacts_already_in_google(google_account)
            delete_contact_groups(existing_groups, google_account)

    log.info("Finished.")
Exemple #6
0
def contacts_list(osm, auth, sections, term=None):
    group = Group(osm, auth, MAPPING.keys(), term)

    for section in sections:
        for member in group.section_all_members(section):
            print("{} {}".format(member['first_name'], member['last_name']))