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: entries = [member2compass(member, section) for member in group.section_yp_members_without_leaders(section)] [check(entry, section) for entry in entries] with open(os.path.join(outdir, section + ".csv"), "w") as csvfile: writer = csv.DictWriter(csvfile, fieldnames=compass_headings) writer.writeheader() [writer.writerow(entry) for entry in entries]
def members_badges(osm, auth, sections, csv=False, no_headers=False, term=None): group = Group(osm, auth, MAPPING.keys(), term) for section in sections: # members = group._sections.sections[Group.SECTIONIDS[section]].members members = group.section_yp_members_without_leaders(section) rows = [] for member in members: badges = member.get_badges(section_type=group.SECTION_TYPE[section]) if badges: # If no badges - probably a leader challenge_new = len([badge for badge in badges if badge['awarded'] == '1' and badge['badge_group'] == '1' and not badge['badge'].endswith('(Pre 2015)')]) challenge_old = len([badge for badge in badges if badge['awarded'] == '1' and badge['badge_group'] == '1' and badge['badge'].endswith('(Pre 2015)')]) activity = len([badge for badge in badges if badge['awarded'] == '1' and badge['badge_group'] == '2']) staged = len([badge for badge in badges if badge['awarded'] == '1' and badge['badge_group'] == '3']) core = len([badge for badge in badges if badge['awarded'] == '1' and badge['badge_group'] == '4']) rows.append([member['date_of_birth'], member['last_name'], member['age'], section, challenge_new, challenge_old, activity, staged, core]) headers = ["DOB", "Last Name", "Age", "Section Name", "Challenge", "Challenge_old", "Staged", "Activity", "Core"] 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, outdir, email, term, do_upload): assert os.path.exists(outdir) and os.path.isdir(outdir) group = Group(osm, auth, update.MAPPING.keys(), term) # Nasty hack to pick up the current term if the user did not # pass in a specific term. actual_term = list(group._sections.sections.values())[0].term['termid'] acc = group._sections._accessor sections = [ {'name': 'Paget', 'id': '9960'}, {'name': 'Swinfen', 'id': '17326'}, {'name': 'Maclean', 'id': '14324'}, {'name': 'Rowallan', 'id': '12700'}, {'name': 'Johnson', 'id': '5882'}, {'name': 'Garrick', 'id': '20711'}, {'name': 'Erasmus', 'id': '20707'}, {'name': 'Somers', 'id': '20706'}, {'name': 'Boswell', 'id': '10363'}, {'name': 'Subs', 'id': '33593'} ] subs_names = ['General Subscriptions', 'Discounted Subscriptions'] subs_types = ['G', 'D'] subs_names_and_types = list(zip(subs_names, subs_types)) all_types = subs_types + ['N', ] al = pd.concat([fetch_section(group, acc, section, actual_term) for section in sections], ignore_index=True) # al[(al['scheme'] == 'Discounted Subscriptions') & ( # al['subs_type'] == 'D')].dropna(axis=1, how='all') # find all members that do not have at least one subscription to either # 'Discounted Subscriptions' or 'General Subscriptions' # filtered by those that have a 'N' in their subscription type. # # all_yp_members = group.all_yp_members_without_leaders() all = [[[_['member_id'], _['first_name'], _['last_name'], _['customisable_data.cf_subs_type_n_g_d_'], section] for _ in group.section_yp_members_without_leaders(section)] for section in group.YP_SECTIONS] all_in_one = list(itertools.chain.from_iterable(all)) all_members_df = pd.DataFrame(all_in_one, columns=( 'scoutid', 'firstname', 'lastname', 'subs_type', 'section')) al_only_subs = al[al['scheme'].isin(subs_names)] # only those that are paying more than one subscription. members_paying_multiple_subs = al_only_subs[ al_only_subs.duplicated('scoutid', take_last=True) | al_only_subs.duplicated('scoutid')] # Calculate file name frm = datetime((date.today() - relativedelta(months=+1)).year, (date.today() - relativedelta(months=+1)).month, 4, 0, 0, 0, tzinfo=tzutc()) to = frm + relativedelta(months=+1) filename = os.path.join(outdir, "{} {} {} {} Subs Report.xls".format(MONTH_MAP[to.month], to.day - 1, to.strftime("%b"), to.year)) with pd.ExcelWriter(filename, engine='xlsxwriter') as writer: # Status of all subs. for scheme in subs_names: al[al['scheme'] == scheme].dropna( axis=1, how='all').to_excel(writer, scheme) # All subs with the correct subs_type for scheme in subs_names_and_types: al[(al['scheme'] == scheme[0]) & (al['subs_type'] == scheme[1])].dropna( axis=1, how='all').to_excel(writer, scheme[0] + "_OK") # All subs with the wrong subs type for scheme in subs_names_and_types: al[(al['scheme'] == scheme[0]) & (al['subs_type'] != scheme[1])].dropna( axis=1, how='all').to_excel(writer, scheme[0] + "_BAD") # Members not in the subs that their sub_type says they should be. for scheme in subs_names_and_types: gen = al[al['scheme'] == scheme[0]].dropna(axis=1, how='all') all_gen_members = all_members_df[ all_members_df['subs_type'] == scheme[1]] all_gen_members['scoutid'] = all_gen_members['scoutid'].astype(str) all_gen_members[~all_gen_members['scoutid'].isin( gen['scoutid'].values)].to_excel(writer, "Not in " + scheme[0]) # All YP members without their subs_type set to anything. all_members_df[~all_members_df['subs_type'].isin( all_types)].to_excel(writer, "Unknown Subs Type") # Members paying multiple subs members_paying_multiple_subs.dropna( axis=1, how='all').to_excel(writer, "Multiple payers") if email: send([email, ], "OSM Subs Report", filename) if do_upload: from gc_accounts import SECTION_MAP, DRIVE_FOLDERS if filename is not None: upload(filename, DRIVE_FOLDERS['Group'], filename=os.path.splitext(os.path.split(filename)[1])[0])