def build_profile(user): # general profile info fname = user.first_name lname = user.last_name email = user.email myewbid = str(user.id) gender = user.get_profile().gender or '' regmember = None if user.get_profile().membership_expiry and user.get_profile().membership_expiry > date.today(): regmember = 'y' chapter = None if user.get_profile().get_chapter(): chapter = user.get_profile().get_chapter().name signins = str(user.get_profile().login_count) lastsignin = str(user.get_profile().current_login) student = '' studentrecords = StudentRecord.objects.filter(user=user, start_date__isnull=False, graduation_date__isnull=True) if studentrecords.count(): student = 'y' else: studentrecords = StudentRecord.objects.filter(user=user, graduation_date__gt=datetime.today()) if studentrecords.count(): student = 'y' else: studentrecords = StudentRecord.objects.filter(user=user, graduation_date__isnull=False) if studentrecords.count(): student = 'n' # otherwise we leave blank, cuz we don't really know... graddate = None studentrecords = StudentRecord.objects.filter(user=user) if studentrecords.count(): for s in studentrecords: if s.graduation_date and (not graddate or graddate < s.graduation_date): graddate = s.graduation_date language = 'en' if user.get_profile().language == 'F': language = 'fr' # build array to send to mailchimp result = {'FNAME': fix_encoding(fname), 'LNAME': fix_encoding(lname), 'EMAIL': email, 'MYEWBID': myewbid, 'GENDER': gender, 'LANGUAGE': language, 'STUDENT': student, 'GRAD_DATE': graddate, 'REGMEMBER': regmember, 'CHAPTER': fix_encoding(chapter), 'SIGNINS': signins, 'LASTSIGNIN': lastsignin } return result
def run_so_csv(group=None): response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=champ_schooloutreach_%d-%d-%d.csv' % (date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow(['Chapter', 'Activity', 'Date', '# Volunteers', 'Prep Hours', 'Execution Hours', 'Created', 'Created By', 'Modified', 'Modified By', 'Confirmed?', 'School Name', 'Teacher Name', 'Teacher Email', 'Teacher Phone', 'Num Presentations', 'Num Students', 'Grades', 'Class', 'Workshop', 'Num Facilitators', 'Num New Facilitators']) metrics = SchoolOutreachMetrics.objects.filter(activity__visible=True) if group: metrics = metrics.filter(activity__group=group) for m in metrics: row = [m.activity.group.name, m.activity.name, m.activity.date, m.activity.numVolunteers, m.activity.prepHours, m.activity.execHours, m.activity.created_date, m.activity.creator.visible_name(), m.activity.modified_date, m.activity.editor.visible_name()] if m.activity.confirmed: row.append('confirmed') else: row.append('unconfirmed') row.extend([m.school_name, m.teacher_name, m.teacher_email, m.teacher_phone, m.presentations, m.students, m.grades, m.subject, m.workshop, m.facilitators, m.new_facilitators]) writer.writerow([fix_encoding(s) for s in row]) return response
def members_csv(request, group_slug): # get basic objects user = request.user group = get_object_or_404(BaseGroup, slug=group_slug) #members = group.get_accepted_members() members = group.members.all() # this includes bulk users... # set up csv response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=myewb-export.csv' writer = csv.writer(response) # headings row = ['First Name', 'Last Name', 'Email', 'Exec title', 'Chapter', 'Date joined this list'] writer.writerow(row) # populate csv for m in members: u = m.user chapters_list = u.get_profile().chapters() chapters = "" for c in chapters_list: chapters = chapters + c.name + "\n" titles_list = GroupMember.objects.filter(user=u, group__in=chapters_list, is_admin=True) titles = "" for t in titles_list: titles = titles + t.admin_title + "\n" row = [u.first_name, u.last_name, u.email, titles, chapters, m.joined] writer.writerow([fix_encoding(s) for s in row]) return response
def members_csv(request, group_slug, regular=False): # get basic objects user = request.user group = get_object_or_404(BaseGroup, slug=group_slug) #members = group.get_accepted_members() members = group.members.all() # this includes bulk users... # set up csv response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=myewb-export.csv' writer = csv.writer(response) # headings row = ['First Name', 'Last Name', 'Email', 'Exec title', 'Chapter', 'Date joined this list', 'Last login', 'Has picture', 'Has address', 'Has workplace'] if regular: row.append('Membership expiry') writer.writerow(row) # populate csv for m in members: u = m.user if not regular or u.get_profile().is_paid_member(): chapter = u.get_profile().chapter if chapter: chaptername = chapter.name title = GroupMember.objects.filter(user=u, group=chapter, is_admin=True) if title.count(): title = title[0].admin_title else: title = "" else: chaptername = "" title = "" has_picture = False if u.avatar_set.count(): has_picture = True has_address = False if u.get_profile().addresses.count(): has_address = True has_workplace = False if u.workrecord_set.count(): has_workplace=True row = [u.first_name, u.last_name, u.email, title, chaptername, m.joined, u.last_login, has_picture, has_address, has_workplace] if regular: row.append(u.get_profile().membership_expiry) writer.writerow([fix_encoding(s) for s in row]) return response
def filesize_for_filename(attachment_path): """ Takes the attachment path and gets the associated file size in bytes. The filesize is formatted using the bytestr method and returned as a string. """ path = os.path.join(settings.MEDIA_ROOT, attachment_path) path = fix_encoding(path) size = os.path.getsize(path) formatted_size = bytestr(size) return {"STATIC_URL": settings.STATIC_URL, "filesize": formatted_size}
def download(request, who=None): if not request.user.has_module_perms('conference'): return render_to_response('denied.html', context_instance=RequestContext(request)) reg = ConferenceRegistration.objects.filter(cancelled=False) if who == 'chapter': reg = reg.filter(user__is_bulk=False, code__isnull=False) elif who == 'open': reg = reg.filter(user__is_bulk=False, type__contains='open') elif reg == 'alumni': reg = reg.filter(user__is_bulk=False, type__contains='alumni') elif reg == 'external': reg = reg.filter(user__is_bulk=True) response = HttpResponse(mimetype='text/csv') response[ 'Content-Disposition'] = 'attachment; filename=confreg_%s_%d-%d-%d.csv' % ( who, date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow([ 'First name', 'Last name', 'Email', 'Gender', 'Chapter', 'amount paid', 'room size', 'registered on', 'headset', 'food prefs', 'special needs', 'emergency name', 'emergency phone', 'prev conferences', 'prev retreats', 'cell phone', 'grouping', 'reg code', 'reg type', 'african delegate' ]) for r in reg: fname = r.user.first_name lname = r.user.last_name email = r.user.email gender = r.user.get_profile().gender if r.user.get_profile().get_chapter(): chapter = r.user.get_profile().get_chapter().name else: chapter = '' row = [ fname, lname, email, gender, chapter, r.amountPaid, r.roomSize, r.date, r.headset, r.foodPrefs, r.specialNeeds, r.emergName, r.emergPhone, r.prevConfs, r.prevRetreats, r.cellphone, r.grouping, r.code, r.type, r.africaFund ] writer.writerow([fix_encoding(s) for s in row]) return response
def download(request, who=None): if not request.user.has_module_perms('conference'): return render_to_response('denied.html', context_instance=RequestContext(request)) reg = ConferenceRegistration.objects.filter(submitted=True, cancelled=False) if who == 'chapter': reg = reg.filter(type='ewb') elif reg == 'alumni': reg = reg.filter(type='alumni') response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=confreg_%s_%d-%d-%d.csv' % (who, date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow(['First name', 'Last name', 'Email', 'Gender', 'Language', 'Who Are You', 'Nametag name', 'Nametag org', 'emergency name', 'emergency phone', 'emergency reln', 'Medical concerns', 'Chapter', 'Role', 'Childcare', 'Childcare contact', 'Accessibility needs', 'Headset', 'Prev conf', 'Prev retreat', 'Registration type', 'Registration code', 'Hotel option', 'Hotel - gender', 'Hotel - sleeping', 'Roommates', 'Hotel requests', 'Food prefs', 'Dietary', 'Special needs', 'Bracelet', 'Handbook', 'Kumvana', 'Leadership day applicaion']) for r in reg: fname = r.user.first_name lname = r.user.last_name email = r.user.email gender = r.user.get_profile().gender language = r.user.get_profile().language if r.code: code = r.code.code else: code = '' row = [fname, lname, email, gender, language, r.whoareyou, r.nametag, r.nametag_org, r.emergName, r.emergPhone, r.emergReln, r.medical, r.chapter, r.role, r.childcare, r.childcare_contact, r.accessibility, r.headset, r.prevConfs, r.prevRetreats, r.type, code, r.hotel, r.hotelgender, r.hotelsleep, r.hotelroommates, r.hotelrequests, r.foodPrefs, r.dietary, r.specialNeeds, r.bracelet, r.handbook, r.africaFund, r.leadership_day] writer.writerow([fix_encoding(s) for s in row]) return response
def filesize_for_filename(attachment_path): """ Takes the attachment path and gets the associated file size in bytes. The filesize is formatted using the bytestr method and returned as a string. """ path = os.path.join(settings.MEDIA_ROOT, attachment_path) path = fix_encoding(path) size = os.path.getsize(path) formatted_size = bytestr(size) return { 'STATIC_URL': settings.STATIC_URL, 'filesize': formatted_size, }
def download(request, who=None): if not request.user.has_module_perms('conference'): return render_to_response('denied.html', context_instance=RequestContext(request)) reg = ConferenceRegistration.objects.filter(cancelled=False) if who == 'chapter': reg = reg.filter(user__is_bulk=False, code__isnull=False) elif who == 'open': reg = reg.filter(user__is_bulk=False, type__contains='open') elif reg == 'alumni': reg = reg.filter(user__is_bulk=False, type__contains='alumni') elif reg == 'external': reg = reg.filter(user__is_bulk=True) response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=confreg_%s_%d-%d-%d.csv' % (who, date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow(['First name', 'Last name', 'Email', 'Gender', 'Chapter', 'amount paid', 'room size', 'registered on', 'headset', 'food prefs', 'special needs', 'emergency name', 'emergency phone', 'prev conferences', 'prev retreats', 'cell phone', 'grouping', 'reg code', 'reg type', 'african delegate']) for r in reg: fname = r.user.first_name lname = r.user.last_name email = r.user.email gender = r.user.get_profile().gender if r.user.get_profile().get_chapter(): chapter = r.user.get_profile().get_chapter().name else: chapter = '' row = [fname, lname, email, gender, chapter, r.amountPaid, r.roomSize, r.date, r.headset, r.foodPrefs, r.specialNeeds, r.emergName, r.emergPhone, r.prevConfs, r.prevRetreats, r.cellphone, r.grouping, r.code, r.type, r.africaFund] writer.writerow([fix_encoding(s) for s in row]) return response
def upload(self, workspace, path, uploadedfile, user): # build relative name filename = uploadedfile.name if path[0:1] != '/': path = '/' + path if path[-1:] != '/': path = path + '/' relpath = path + filename relpath = fix_encoding(relpath) # see if this file already exists (update, not create) workfile = self.load(workspace, relpath) if workfile: # shouldn't happen, but just in case... if not workfile.creator: workfile.creator = user workfile.save() # update metadata workfile.update(uploadedfile, user) else: # find absolute directory abspath = workspace.get_dir(path) # filename validation: strip out illegal characters escaped_filename = re_filename.sub(r'', filename) if escaped_filename != filename: relpath = path + escaped_filename # open file diskfile = open(abspath + escaped_filename, 'wb+') # write file to disk for chunk in uploadedfile.chunks(): diskfile.write(chunk) diskfile.close() # save metadata workfile = self.create(workspace=workspace, name=relpath, creator=user, updator=user) return workfile
def read(self, request): # grab all of the applicable filters allowed_filters = [ 'chapter', 'year', 'role', 'page', 'last_name', 'search', 'registered', ] filters = dict([(str(fix_encoding(k)), str(fix_encoding(v))) for (k, v) in request.GET.items() if k in allowed_filters]) if filters.get('role', None) == 'm': del filters['role'] if filters.get('year', None): filters['year'] = int(filters['year']) # pop off the filters that won't be kwargs to our manager function page = int(filters.pop('page', 1)) last_name = filters.pop('last_name', None) search = filters.pop('search', None) registered = filters.pop('registered', None) try: # grab all matching cohorts and put their users together if filters: all_cohorts = Cohort.objects.filter(**filters) all_cps = ConferenceProfile.objects.none() for cohort in all_cohorts: all_cps = all_cps | cohort.members.all() else: all_cps = ConferenceProfile.objects.all() # querysets created with | with duplicates # get distinct results and order them cps = all_cps.distinct() # add last_name filter if last_name is not None: cps = cps.filter( member_profile__last_name__istartswith=last_name) # add name search filter if search is not None: terms = search.split(' ') print terms for search_term in terms: cps = cps.filter( member_profile__name__icontains=search_term) # add the registered_filter if registered == 'true': cps = cps.filter(registered=False) # order cps = cps.order_by('-registered', 'member_profile__name') # paginate paged_cps = cps[(page - 1) * PAGE_SIZE:page * PAGE_SIZE] # search for a valid cohort with the given params cohort_props = { 'chapter': None, 'year': None, 'role': None, } # update our none values with the filters passed in cohort_props.update(filters) if cohort_props['role'] is None and cohort_props[ 'chapter'] is not None and cohort_props['year'] is not None: # use member role for cohort opt-ing in reasons cohort_props['role'] = 'm' # try to get a valid cohort try: cohort = Cohort.objects.get(**cohort_props) except Cohort.DoesNotExist: cohort = None except Exception, e: resp = rc.BAD_REQUEST resp.write('The filters you provided were not valid. %s %s' % (str(filters), e)) return resp
def build_profile(user): # general profile info fname = user.first_name lname = user.last_name email = user.email myewbid = str(user.id) gender = user.get_profile().gender or '' regmember = None if user.get_profile().membership_expiry and user.get_profile( ).membership_expiry > date.today(): regmember = 'y' chapter = None if user.get_profile().get_chapter(): chapter = user.get_profile().get_chapter().name signins = str(user.get_profile().login_count) lastsignin = str(user.get_profile().current_login) student = '' studentrecords = StudentRecord.objects.filter( user=user, start_date__isnull=False, graduation_date__isnull=True) if studentrecords.count(): student = 'y' else: studentrecords = StudentRecord.objects.filter( user=user, graduation_date__gt=datetime.today()) if studentrecords.count(): student = 'y' else: studentrecords = StudentRecord.objects.filter( user=user, graduation_date__isnull=False) if studentrecords.count(): student = 'n' # otherwise we leave blank, cuz we don't really know... graddate = None studentrecords = StudentRecord.objects.filter(user=user) if studentrecords.count(): for s in studentrecords: if s.graduation_date and (not graddate or graddate < s.graduation_date): graddate = s.graduation_date language = 'en' if user.get_profile().language == 'F': language = 'fr' # build array to send to mailchimp result = { 'FNAME': fix_encoding(fname), 'LNAME': fix_encoding(lname), 'EMAIL': email, 'MYEWBID': myewbid, 'GENDER': gender, 'LANGUAGE': language, 'STUDENT': student, 'GRAD_DATE': graddate, 'REGMEMBER': regmember, 'CHAPTER': fix_encoding(chapter), 'SIGNINS': signins, 'LASTSIGNIN': lastsignin } return result
def run(): mc = MailChimp(key) list = settings.MAILCHIMP_LISTID # ---------------------------------------------------------------------- # handle unsubscribes first emails = [] unsub = ListEvent.objects.filter(subscribe=False) for u in unsub: print "unsubscribing", fix_encoding(u.user.visible_name()), u.email emails.append(u.email) u.delete() if len(emails): result = mc.listBatchUnsubscribe(id=list, emails=emails, delete_member=True, send_goodbye=False, send_notify=False) print_result(result) # ---------------------------------------------------------------------- # subscribe new people # (actually, this should never be used... since new subscriptions have # been rolled into ProfileEvents) emails = [] sub = ListEvent.objects.filter(subscribe=True) for s in sub: print "subscribing", fix_encoding( s.user.visible_name()), s.user.email entry = build_profile(s.user) entry['GROUPINGS'] = build_new_groups(s.user) emails.append(entry) s.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails, double_optin=False, update_existing=False) print_result(result) # ---------------------------------------------------------------------- # profile info updates # handle email address changes separately, since we can't batch those profile = ProfileEvent.objects.filter(email__isnull=False) for p in profile: if p.email: print "updating with new email", fix_encoding( p.user.visible_name()), p.email, p.user.email entry = build_profile(p.user) entry['GROUPINGS'] = build_new_groups(p.user) p.delete() result = mc.listSubscribe(id=list, email_address=p.email, merge_vars=entry, double_optin=False, send_welcome=False, update_existing=True, replace_interests=False) print result # and everything else profile = ProfileEvent.objects.all() for p in profile: print "updating", fix_encoding(p.user.visible_name()), p.user.email entry = build_profile(p.user) entry['GROUPINGS'] = build_new_groups(p.user) emails.append(entry) p.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails, double_optin=False, update_existing=True, replace_interests=False) print_result(result) # ---------------------------------------------------------------------- # group joins emails = {} join = GroupEvent.objects.filter(join=True) for j in join: print fix_encoding( j.user.visible_name()), j.user.email, "joining", fix_encoding( j.group.name) # if they're not already on the list, build a profile for them if not emails.has_key(j.user.id): emails[j.user.id] = build_profile(j.user) emails[j.user.id]['GROUPINGS'] = [] # add this group to the user's list of groups emails[j.user.id]['GROUPINGS'] = add_group( j.group, emails[j.user.id]['GROUPINGS']) # ok, done. j.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails.values(), double_optin=False, update_existing=True, replace_interests=False) print_result(result) # ---------------------------------------------------------------------- # group leaves emails = {} leave = GroupEvent.objects.filter(join=False) for l in leave: print fix_encoding( l.user.visible_name()), l.user.email, "leaving", fix_encoding( l.group.name) # if they're not already on the list, build a profile for them try: if l.user.id not in emails: emails[l.user.id] = build_profile(l.user) info = mc.listMemberInfo(id=list, email_address=l.user.email) emails[ l.user.id]['GROUPINGS'] = info['merges']['GROUPINGS'] # remove group from list emails[l.user.id]['GROUPINGS'] = remove_group( l.group, emails[l.user.id]['GROUPINGS']) except: print "--ERROR" # ok, done. l.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails.values(), double_optin=False, update_existing=True, replace_interests=True) print_result(result)
def read(self, request): # grab all of the applicable filters allowed_filters = ['chapter', 'year', 'role', 'page', 'last_name', 'search', 'registered',] filters = dict([(str(fix_encoding(k)), str(fix_encoding(v))) for (k, v) in request.GET.items() if k in allowed_filters]) if filters.get('role', None) == 'm': del filters['role'] if filters.get('year', None): filters['year'] = int(filters['year']) # pop off the filters that won't be kwargs to our manager function page = int(filters.pop('page', 1)) last_name = filters.pop('last_name', None) search = filters.pop('search', None) registered = filters.pop('registered', None) try: # grab all matching cohorts and put their users together if filters: all_cohorts = Cohort.objects.filter(**filters) all_cps = ConferenceProfile.objects.none() for cohort in all_cohorts: all_cps = all_cps | cohort.members.all() else: all_cps = ConferenceProfile.objects.all() # querysets created with | with duplicates # get distinct results and order them cps = all_cps.distinct() # add last_name filter if last_name is not None: cps = cps.filter(member_profile__last_name__istartswith=last_name) # add name search filter if search is not None: terms = search.split(' ') print terms for search_term in terms: cps = cps.filter(member_profile__name__icontains=search_term) # add the registered_filter if registered == 'true': cps = cps.filter(registered=False) # order cps = cps.order_by('-registered', 'member_profile__name') # paginate paged_cps = cps[(page-1)*PAGE_SIZE:page*PAGE_SIZE] # search for a valid cohort with the given params cohort_props = { 'chapter': None, 'year': None, 'role': None, } # update our none values with the filters passed in cohort_props.update(filters) if cohort_props['role'] is None and cohort_props['chapter'] is not None and cohort_props['year'] is not None: # use member role for cohort opt-ing in reasons cohort_props['role'] = 'm' # try to get a valid cohort try: cohort = Cohort.objects.get(**cohort_props) except Cohort.DoesNotExist: cohort = None except Exception, e: resp = rc.BAD_REQUEST resp.write('The filters you provided were not valid. %s %s' % (str(filters), e)) return resp
def run_full_csv(group=None): response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=champ_activities_%d-%d-%d.csv' % (date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow(['Chapter', 'Activity', 'Description', 'Full Date', 'Month', 'Planning Year', '# Volunteers', 'Prep Hours', 'Execution Hours', 'Goals', 'Outcomes', 'Created', 'Created By', 'Modified', 'Modified By', 'Confirmed?', '# Purposes', 'Purpose(s)', 'ML?', 'SO?', 'Functioning?', 'Engagement?', 'Advocacy?', 'Publicity?', 'Fundraising?', 'WO?', 'CE?', 'ML - Type', 'ML - LP Related', 'ML - Curriculum', 'ML - Resources By', 'ML - Duration', 'ML - Attendence', 'ML - New Attendence', 'SO - School Name', 'SO - Teacher Name', 'SO - Teacher Email', 'SO - Teacher Phone', 'SO- Num Presentations', 'SO - Num Students', 'SO - Grades', 'SO - Class', 'SO - Workshop', 'SO - Num Facilitators', 'SO - Num New Facilitators', 'Functioning - Type', 'Functioning - Location', 'Functioning - Purpose', 'Functioning - Attendence', 'Functioning - Duration', 'Engagement - Type', 'Engagement - Location', 'Engagement - Purpose', 'Engagement - Subject', 'Engagement - Level1', 'Engagement - Level2', 'Engagement - Level3', 'Advocacy - Type', 'Advocacy - Units', 'Advocacy - DecisionMaker', 'Advocacy - Position', 'Advocacy - EWB', 'Advocacy - Purpose', 'Advocacy - Learned', 'Publicity - Outlet', 'Publicity - Type', 'Publicity - Location', 'Publicity - Issue', 'Publicity - Circulation', 'Fundraising - Goal', 'Fundraising - Revenue', 'Fundraising - Repeat', 'WO - Company', 'WO - City', 'WO - Presenters', 'WO - Ambassador', 'WO - Email', 'WO - Phone', 'WO - NumPresentations', 'WO - Attendence', 'WO - Type', 'CE - Name', 'CE - Code', 'CE - NumStudents', 'CE - ClassHours', 'CE - Professor', 'CE - Activity']) activities = Activity.objects.filter(visible=True) if group: activities = activities.filter(group=group) for a in activities: impact, func, ml, so, pe, pa, wo, ce, pub, fund = a.get_metrics(pad=True) row = [a.group.name, a.name] if impact: row.append(impact.description) else: row.append('') row.extend([a.date, a.date.strftime('%B'), schoolyear.school_year_name(a.date), a.numVolunteers, a.prepHours, a.execHours]) if impact: row.extend([impact.goals, impact.outcome]) else: row.extend(['', '']) row.extend([a.created_date, a.creator.visible_name(), a.modified_date, a.editor.visible_name()]) if a.confirmed: row.append('confirmed') else: row.append('unconfirmed') row.append(len(a.get_metrics()) - 1) purposes = '' for m in a.get_metrics(): if not m.metricname == 'all': purposes = purposes + m.metricname + '-' if len(purposes): purposes = purposes[0:-1] row.append(purposes) if ml: row.append('1') else: row.append('0') if so: row.append('1') else: row.append('0') if func: row.append('1') else: row.append('0') if pe: row.append('1') else: row.append('0') if pa: row.append('1') else: row.append('0') if pub: row.append('1') else: row.append('0') if fund: row.append('1') else: row.append('0') if wo: row.append('1') else: row.append('0') if ce: row.append('1') else: row.append('0') if ml: row.append(ml.type) if ml.learning_partner: row.append('1') else: row.append('0') row.extend([ml.curriculum, ml.resources_by, ml.duration, ml.attendance, ml.new_attendance]) else: row.extend(['', '', '', '', '', '', '']) if so: row.extend([so.school_name, so.teacher_name, so.teacher_email, so.teacher_phone, so.presentations, so.students, so.grades, so.subject, so.workshop, so.facilitators, so.new_facilitators]) else: row.extend(['', '', '', '', '', '', '', '', '', '', '']) if func: row.extend([func.type, func.location, func.purpose, func.attendance, func.duration]) else: row.extend(['', '', '', '', '']) if pe: row.extend([pe.type, pe.location, pe.purpose, pe.subject, pe.level1, pe.level2, pe.level3]) else: row.extend(['', '', '', '', '', '', '']) if pa: row.extend([pa.type, pa.units, pa.decision_maker, pa.position, pa.ewb, pa.purpose, pa.learned]) else: row.extend(['', '', '', '', '', '', '']) if pub: row.extend([pub.outlet, pub.type, pub.location, '', pub.circulation]) else: row.extend(['', '', '', '', '']) if fund: row.extend([fund.goal, fund.revenue, '']) else: row.extend(['', '', '']) if wo: row.extend([wo.company, wo.city, wo.presenters, wo.ambassador, wo.email, wo.phone, wo.presentations, wo.attendance, wo.type]) else: row.extend(['', '', '', '', '', '', '', '', '']) if ce: row.extend([ce.name, ce.code, ce.students, ce.hours, ce.professor, ce.ce_activity]) else: row.extend(['', '', '', '', '', '']) writer.writerow([fix_encoding(s) for s in row]) return response
def run(): mc = MailChimp(key) list = settings.MAILCHIMP_LISTID # ---------------------------------------------------------------------- # handle unsubscribes first emails = [] unsub = ListEvent.objects.filter(subscribe=False) for u in unsub: print "unsubscribing", to_ascii(u.user.visible_name()), u.email emails.append(u.email) u.delete() if len(emails): result = mc.listBatchUnsubscribe(id=list, emails=emails, delete_member=True, send_goodbye=False, send_notify=False) print_result(result) # ---------------------------------------------------------------------- # subscribe new people # (actually, this should never be used... since new subscriptions have # been rolled into ProfileEvents) emails = [] sub = ListEvent.objects.filter(subscribe=True) for s in sub: print "subscribing", to_ascii(s.user.visible_name()), s.user.email entry = build_profile(s.user) entry['GROUPINGS'] = build_new_groups(s.user) emails.append(entry) s.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails, double_optin=False, update_existing=False) print_result(result) # ---------------------------------------------------------------------- # profile info updates # handle email address changes separately, since we can't batch those profile = ProfileEvent.objects.filter(email__isnull=False) for p in profile: if p.email: print "updating with new email", to_ascii(p.user.visible_name()), p.email, p.user.email entry = build_profile(p.user) entry['GROUPINGS'] = build_new_groups(p.user) p.delete() result = mc.listSubscribe(id=list, email_address=p.email, merge_vars=entry, double_optin=False, send_welcome=False, update_existing=True, replace_interests=False) print result # and everything else profile = ProfileEvent.objects.all() for p in profile: print "updating", to_ascii(p.user.visible_name()), p.user.email entry = build_profile(p.user) entry['GROUPINGS'] = build_new_groups(p.user) emails.append(entry) p.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails, double_optin=False, update_existing=True, replace_interests=False) print_result(result) # ---------------------------------------------------------------------- # group joins emails = {} join = GroupEvent.objects.filter(join=True) for j in join: print to_ascii(j.user.visible_name()), j.user.email, "joining", fix_encoding(j.group.name) # if they're not already on the list, build a profile for them if not emails.has_key(j.user.id): emails[j.user.id] = build_profile(j.user) emails[j.user.id]['GROUPINGS'] = [] # add this group to the user's list of groups emails[j.user.id]['GROUPINGS'] = add_group(j.group, emails[j.user.id]['GROUPINGS']) # ok, done. j.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails.values(), double_optin=False, update_existing=True, replace_interests=False) print_result(result) # ---------------------------------------------------------------------- # group leaves emails = {} leave = GroupEvent.objects.filter(join=False) for l in leave: print to_ascii(l.user.visible_name()), l.user.email, "leaving", fix_encoding(l.group.name) # if they're not already on the list, build a profile for them try: if l.user.id not in emails: emails[l.user.id] = build_profile(l.user) info = mc.listMemberInfo(id=list, email_address=l.user.email) emails[l.user.id]['GROUPINGS'] = info['merges']['GROUPINGS'] # remove group from list emails[l.user.id]['GROUPINGS'] = remove_group(l.group, emails[l.user.id]['GROUPINGS']) except: print "--ERROR" # ok, done. l.delete() if len(emails): result = mc.listBatchSubscribe(id=list, batch=emails.values(), double_optin=False, update_existing=True, replace_interests=True) print_result(result)
def run_full_csv(group=None): response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=champ_activities_%d-%d-%d.csv' % (date.today().month, date.today().day, date.today().year) writer = csv.writer(response) writer.writerow(['Chapter', 'Activity', 'Description', 'Full Date', 'Month', 'Planning Year', '# Volunteers', 'Prep Hours', 'Execution Hours', 'Goals', 'Outcomes', 'Created', 'Created By', 'Modified', 'Modified By', 'Confirmed?', '# Purposes', 'Purpose(s)', 'ML?', 'SO?', 'Functioning?', 'Engagement?', 'Advocacy meetings?', 'Letter writing?', 'Publicity?', 'Fundraising?', 'WO?', 'CE?', 'ML - Type', 'ML - LP Related', 'ML - Focus', 'ML - Source', 'ML - Duration', 'ML - Attendence', 'ML - New Attendence', 'SO - School Name', 'SO - Teacher Name', 'SO - Teacher Email', 'SO - Teacher Phone', 'SO- Num Presentations', 'SO - Num Students', 'SO - Grades', 'SO - Class', 'SO - Workshop', 'SO - Num Facilitators', 'SO - Num New Facilitators', 'Functioning - Type', 'Functioning - Location', 'Functioning - Purpose', 'Functioning - Attendence', 'Functioning - Duration', 'Engagement - Type', 'Engagement - Location', 'Engagement - Purpose', 'Engagement - Subject', 'Engagement - Level1', 'Engagement - Level2', 'Engagement - Level3', 'Advocacy - Type', 'Advocacy - Units', 'Advocacy - DecisionMaker', 'Advocacy - Position', 'Advocacy - EWB', 'Advocacy - Purpose', 'Advocacy - Learned', 'Letters - signatures', 'Letters - to decisionmakers', 'Letters - to media', 'Letters - other', 'Publicity - Outlet', 'Publicity - Type', 'Publicity - Location', 'Publicity - Issue', 'Publicity - Circulation', 'Fundraising - Goal', 'Fundraising - Revenue', 'Fundraising - Repeat', 'WO - Company', 'WO - City', 'WO - Presenters', 'WO - Ambassador', 'WO - Email', 'WO - Phone', 'WO - NumPresentations', 'WO - Attendence', 'WO - Type', 'CE - Name', 'CE - Code', 'CE - NumStudents', 'CE - ClassHours', 'CE - Professor', 'CE - Activity']) start = date(2009, 9, 1) end = date.today() activities = Activity.objects.filter(visible=True, date__range=(start, end)) if group: activities = activities.filter(group=group) for a in activities: impact, func, ml, so, pe, pa, adv, wo, ce, pub, fund = a.get_metrics(pad=True) row = [a.group.name, a.name] if impact: row.append(impact.description) else: row.append('') formatted_time = '' if a.date: formatted_time = a.date.strftime('%B') row.extend([a.date, formatted_time, schoolyear.school_year_name(a.date), a.numVolunteers, a.prepHours, a.execHours]) if impact: row.extend([impact.goals, impact.outcome]) else: row.extend(['', '']) row.extend([a.created_date, a.creator.visible_name(), a.modified_date, a.editor.visible_name()]) if a.confirmed: row.append('confirmed') else: row.append('unconfirmed') row.append(len(a.get_metrics()) - 1) purposes = '' for m in a.get_metrics(): if not m.metricname == 'all': purposes = purposes + m.metricname + '-' if len(purposes): purposes = purposes[0:-1] row.append(purposes) if ml: row.append('1') else: row.append('0') if so: row.append('1') else: row.append('0') if func: row.append('1') else: row.append('0') if pe: row.append('1') else: row.append('0') if pa: row.append('1') else: row.append('0') if adv: row.append('1') else: row.append('0') if pub: row.append('1') else: row.append('0') if fund: row.append('1') else: row.append('0') if wo: row.append('1') else: row.append('0') if ce: row.append('1') else: row.append('0') if ml: row.append(ml.type) if ml.learning_partner: row.append('1') else: row.append('0') row.extend([ml.curriculum, ml.resources_by, ml.duration, ml.attendance, ml.new_attendance]) else: row.extend(['', '', '', '', '', '', '']) if so: row.extend([so.school_name, so.teacher_name, so.teacher_email, so.teacher_phone, so.presentations, so.students, so.grades, so.subject, so.workshop, so.facilitators, so.new_facilitators]) else: row.extend(['', '', '', '', '', '', '', '', '', '', '']) if func: row.extend([func.type, func.location, func.purpose, func.attendance, func.duration]) else: row.extend(['', '', '', '', '']) if pe: row.extend([pe.type, pe.location, pe.purpose, pe.subject, pe.level1, pe.level2, pe.level3]) else: row.extend(['', '', '', '', '', '', '']) if pa: row.extend([pa.type, pa.units, pa.decision_maker, pa.position, pa.ewb, pa.purpose, pa.learned]) else: row.extend(['', '', '', '', '', '', '']) if adv: row.extend([adv.signatures, adv.letters, adv.editorials, adv.other]) else: row.extend(['', '', '', '']) if pub: row.extend([pub.outlet, pub.type, pub.location, '', pub.circulation]) else: row.extend(['', '', '', '', '']) if fund: row.extend([fund.goal, fund.revenue, '']) else: row.extend(['', '', '']) if wo: row.extend([wo.company, wo.city, wo.presenters, wo.ambassador, wo.email, wo.phone, wo.presentations, wo.attendance, wo.type]) else: row.extend(['', '', '', '', '', '', '', '', '']) if ce: row.extend([ce.name, ce.code, ce.students, ce.hours, ce.professor, ce.ce_activity]) else: row.extend(['', '', '', '', '', '']) writer.writerow([fix_encoding(s) for s in row]) return response
def activity_as_pdf(request, group_slug, activity_id): group = get_object_or_404(Network, slug=group_slug) activity = get_object_or_404(Activity, pk=activity_id) if not activity.group.pk == group.pk: return HttpResponseForbidden() try: from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import letter from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import Paragraph, Image, Spacer, SimpleDocTemplate from reportlab.lib import enums import settings except: return HttpResponse("Missing library") width, pageHeight = letter response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=champ_activity.pdf' stylesheet = getSampleStyleSheet() normalStyle = copy.deepcopy(stylesheet['Normal']) normalStyle.fontName = 'Times-Roman' normalStyle.fontSize = 12 normalStyle.leading = 15 bold = copy.deepcopy(normalStyle) bold.fontName = 'Times-Bold' bold.leftIndent = 6 rightAlign = copy.deepcopy(normalStyle) rightAlign.alignment = enums.TA_RIGHT lindent = copy.deepcopy(normalStyle) lindent.leftIndent = 12 bground = copy.deepcopy(normalStyle) bground.backColor = '#e0e0e0' h1 = copy.deepcopy(normalStyle) h1.fontName = 'Times-Bold' h1.fontSize = 18 h1.leading = 22 h1.backColor = '#d0d0d0' h1.borderPadding = 3 h1.spaceBefore = 3 h1.spaceAfter = 3 h2 = copy.deepcopy(normalStyle) h2.fontName = 'Times-Bold' h2.fontSize = 14 h2.leading = 18 h2.backColor = '#e8e8e8' h2.borderPadding = 3 h2.spaceBefore = 3 h2.spaceAfter = 3 page = SimpleDocTemplate(response, pagesize=letter, title="EWB Event Summary") p = [] p.append(Paragraph("Engineers Without Borders Canada", normalStyle)) p.append(Paragraph("Event Summary", normalStyle)) p.append(Spacer(0, -50)) img = Image(settings.MEDIA_ROOT + '/images/emaillogo.jpg', 100, 51) img.hAlign = 'RIGHT' p.append(img) #p.line(50, height - 90, width - 50, height - 90) p.append(Spacer(0, 10)) p.append(Paragraph("<strong>" + str(activity.date) + "</strong>", rightAlign)) p.append(Paragraph("Printed: " + str(date.today()), rightAlign)) p.append(Spacer(0, -20)) p.append(Paragraph("<strong>" + group.chapter_info.chapter_name + "</strong>", normalStyle)) p.append(Spacer(0, 20)) p.append(Paragraph(activity.name, h1)) p.append(Spacer(0, 10)) p.append(Paragraph("<strong>Volunters:</strong> " + str(activity.numVolunteers), normalStyle)) p.append(Paragraph("<strong>Prep time:</strong> " + str(activity.prepHours) + " person hours", normalStyle)) p.append(Paragraph("<strong>Execution time:</strong> " + str(activity.execHours) + " person hours", normalStyle)) p.append(Spacer(0, 10)) for m in activity.get_metrics(): metricname = '' for mshort, mlong in ALLMETRICS: if mshort == m.metricname: metricname = mlong p.append(Paragraph(metricname, h2)) for x, y in m.get_values().items(): if x and y: p.append(Paragraph(fix_encoding(str(x)), bold)) p.append(Paragraph(fix_encoding(str(y)), lindent)) p.append(Spacer(0, 10)) p.append(Spacer(0, 10)) page.build(p) return response
def done(self, request, cleaned_data): #product = Product.objects.get(sku=cleaned_data['products']) address = get_object_or_none(Address, pk=cleaned_data['address']) if not address or not request.user.get_profile() == address.content_object: address = Address() address.street = '366 Adelaide' address.city = 'Toronto' address.province = 'ON' address.postal_code = 'M5V1R9' address.country = 'CA' # stuff necessary values into dictionary... to be encoded. param = {'trnCardOwner': cleaned_data['billing_name'], 'trnCardNumber': cleaned_data['cc_number'], 'trnExpMonth': cleaned_data['cc_expiry'].split('/')[0], 'trnExpYear': cleaned_data['cc_expiry'].split('/')[1], 'ordName': cleaned_data['billing_name'], 'ordEmailAddress': cleaned_data['email'], 'ordPhoneNumber': cleaned_data['phone'], 'ordAddress1': address.street, 'ordAddress2': '', 'ordCity':address.city, 'ordProvince': address.province, 'ordPostalCode': address.postal_code, 'ordCountry': address.country, 'requestType': 'BACKEND', 'trnOrderNumber': '%s' % int(time.time()), 'merchant_id': settings.TD_MERCHANT_ID, } product_count = 1 total_cost = 0 product_list = [] if isinstance(cleaned_data['products'],ListType): for sku in cleaned_data['products']: product = Product.objects.get(sku=sku) param['prod_id_%s' % product_count] = product.sku param['prod_quantity_%s' % product_count] = '1' param['prod_name_%s' % product_count] = product.name param['prod_cost_%s' % product_count] = product.amount total_cost += Decimal(product.amount) product_count = product_count + 1 product_list.append(product) else: product = Product.objects.get(sku=cleaned_data['products']) param['prod_id_1'] = product.sku param['prod_quantity_1'] = '1' param['prod_name_1'] = product.name param['prod_cost_1'] = product.amount total_cost += Decimal(product.amount) product_list.append(product) param['trnAmount'] = total_cost if total_cost > 0: #param = [fix_encoding(p) for p in param] fixed_param = {} for x, y in param.items(): fixed_param[x] = fix_encoding(y) encoded = urllib.urlencode(fixed_param) # push the transaction to the bank handle = urllib.urlopen(settings.TD_MERCHANT_URL, encoded) result = handle.read().split('&') # parse the result string back into a dictionary results = {} for r in result: r2 = r.split('=') r2[0] = urllib.unquote_plus(r2[0]) r2[1] = urllib.unquote_plus(r2[1]) results[r2[0]] = r2[1] # TODO: any other processing/recordkeeping we want to do? # do I want to save this into the db? p = Payment() p.cc_type = cleaned_data['cc_type'] p.billing_name=cleaned_data['billing_name'] p.phone=cleaned_data['phone'] p.email=cleaned_data['email'] p.approved=results['trnApproved'] p.response="\n".join(result) p.amount = total_cost p.save() for prod in product_list: p.products.add(prod) p.save() # return based on value if results['trnApproved'] == '1': # send receipt message = loader.get_template("creditcard/receipt.html") c = Context({'name': cleaned_data['billing_name'], 'date': datetime.today(), 'txid': results['trnOrderNumber'], 'product': product_list, 'amount': total_cost}) body = message.render(c) send_mail(subject='Credit Card Receipt', txtMessage=body, htmlMessage=None, fromemail='Engineers Without Borders Canada <*****@*****.**>', recipients=[cleaned_data['email']], use_template=False) # return success return (True, results['trnId'], results['trnOrderNumber']) else: return (False, results['messageText']) else: return (True, '00000', '00000')
def send_to_watchlist(self): """ Sends an email to everyone who is watching this thread, and/or to post owner. We assume that comments can only be made on topics, which is technically false (it uses a generic foreign key) - but in our use of it, it holds. Will need to change this function if we ever decide to allow comments on other types of objects. """ # only run this if it is attached to a GroupTopic # (yeah, this is bad design... TODO refactor to be cleaner) topic_type = ContentType.objects.get_for_model(GroupTopic) if self.content_type != topic_type: return False # build email topic = self.content_object attachments = Attachment.objects.attachments_for_object(self) ctx = {'group': topic.group, 'title': topic.title, 'topic_id': topic.pk, 'reply_id': self.pk, 'event': None, 'attachments': attachments } if topic.group.group_type == 'd': sender = '"%s %s" <%s>' % (self.user.get_profile().first_name, self.user.get_profile().last_name, self.user.email) reply_to = self.user.email topic.group.send_mail_to_members(topic.title, self.comment, sender=sender, context=ctx, content_object=self, reply_to=reply_to) sender = 'myEWB <*****@*****.**>' recipients = set() # loop through watchlists and send emails for list in topic.watchlists.all(): user = list.owner # TODO: for user in list.subscribers blah blah if user.get_profile().watchlist_as_emails and not user.nomail: recipients.add(user.email) # send email to original post creator if topic.creator.get_profile().replies_as_emails and not topic.creator.nomail: recipients.add(topic.creator.email) # send email to participants participants = [] allcomments = ThreadedComment.objects.all_for_object(topic) for c in allcomments: if c.user.get_profile().replies_as_emails2 and not c.user.nomail: recipients.add(c.user.email) # but remove original poster if self.user.email in recipients: recipients.remove(self.user.email) # also remove all people who've already been emailed (can this be more efficient?) groupmembers = set(topic.group.get_member_emails()) recipients -= groupmembers messagebody = """<p>Hello</p> <p> %s has replied to the post <em>%s</em> on myEWB: </p> <div style="margin: 10px; padding: 10px; border: 1px solid;"> %s </div> <p>You are receiving this email because you have participated in this conversation or added it to your watchlist. To change your email preferences, <a href="http://my.ewb.ca%s">click here</a>. </p> """ % (fix_encoding(self.user.visible_name()), fix_encoding(topic.title), fix_encoding(self.comment), reverse('profile_settings')) if len(recipients): send_mail(subject="Re: %s" % topic.title, txtMessage=None, htmlMessage=messagebody, fromemail=sender, recipients=recipients, context=ctx, shortname=topic.group.slug, content_object=self)