def campaign_action_csv(campaign, action): if action.type not in ('Y', 'N', 'M', 'F'): abort(403) outfile = StringIO() out = unicodecsv.writer(outfile, 'excel') out.writerow(['fullname', 'username', 'email', 'phone']) for ua in action.useractions: out.writerow([ua.user.fullname, ua.user.username, ua.user.email, ua.user.phone]) return outfile.getvalue(), 200, {'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="%s-%s.csv"' % ( make_name(campaign.title), make_name(action.title))}
def rename(self, title): name = make_name(title) if self.query.filter_by(name=name).first() is not None: raise ValueError(u"Name already in use") else: self.name = name self.title = title
def proposal_new(space): form = ProposalForm(model=Proposal, parent=space) # del form.session_type # We don't use this anymore # But The Goa Project still does, so commented out form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email form.phone.data = g.user.phone if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) if form.speaking.data: proposal.speaker = g.user else: proposal.speaker = None with db.session.no_autoflush: proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal) proposal.name = make_name(proposal.title) db.session.add(proposal) db.session.commit() flash(_("Your new session has been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_template('baseframe/autoform.html', form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), breadcrumbs=[(space.url_for(), space.title)], message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.')))
def get(cls, tag, create=False): name = make_name(tag) ob = cls.query.filter_by(name=name).one_or_none() if create and not ob: ob = cls(title=tag[:cls.__name_length__]) db.session.add(ob) return ob
def proposal_new(profile, space): form = ProposalForm(model=Proposal, parent=space) del form.session_type # We don't use this anymore if space.inherit_sections: form.section.query = ProposalSpaceSection.query.filter( or_(ProposalSpaceSection.proposal_space == space, ProposalSpaceSection.proposal_space == space.parent_space), ProposalSpaceSection.public == True).order_by('title') else: form.section.query = ProposalSpaceSection.query.filter( ProposalSpaceSection.proposal_space == space, ProposalSpaceSection.public == True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email form.phone.data = g.user.phone if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) with db.session.no_autoflush: proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal.formdata) proposal.name = make_name(proposal.title) db.session.add(proposal) db.session.commit() flash(_("Your new session has been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_form( form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' )))
def proposal_edit(profile, space, proposal): form = ProposalForm(obj=proposal.formdata, model=Proposal, parent=space) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by("title") if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if proposal.user != g.user: del form.speaking if form.validate_on_submit(): form.populate_obj(proposal.formdata) proposal.name = make_name(proposal.title) proposal.edited_at = datetime.utcnow() db.session.commit() flash(_("Your changes have been saved"), "info") return redirect(proposal.url_for(), code=303) return render_form( form=form, title=_("Edit session proposal"), submit=_("Save changes"), message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.') ), )
def proposal_edit(space, proposal): form = ProposalForm(obj=proposal, model=Proposal, parent=space) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if proposal.user != g.user: del form.speaking elif request.method == 'GET': form.speaking.data = proposal.speaker == g.user if form.validate_on_submit(): form.populate_obj(proposal) proposal.name = make_name(proposal.title) if proposal.user == g.user: # Only allow the speaker to change this status if form.speaking.data: proposal.speaker = g.user else: if proposal.speaker == g.user: proposal.speaker = None proposal.edited_at = datetime.utcnow() db.session.commit() flash(_("Your changes have been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_template('baseframe/autoform.html', form=form, title=_("Edit session proposal"), submit=_("Save changes"), breadcrumbs=[(space.url_for(), space.title), (proposal.url_for(), proposal.title)], message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.')))
def import_from_csv(campaign, reader): existing = set([r.email.lower() for r in db.session.query(EmailRecipient.email).filter(EmailRecipient.campaign == campaign).all()]) fields = set(campaign.fields) for row in reader: row = dict([(make_name(key), value.strip()) for key, value in row.items()]) fullname = firstname = lastname = email = nickname = None # The first column in each of the following is significant as that is the field name # in the EmailRecipient model and is the name passed to the email template # Now look for email (mandatory), first name, last name and full name for field in ['email', 'e-mail', 'email-id', 'e-mail-id', 'email-address', 'e-mail-address']: if field in row and row[field]: email = row[field] del row[field] break if not email: continue # XXX: Cheating! Don't hardcode for Funnel's columns for field in ['fullname', 'name', 'full-name', 'speaker', 'proposer']: if field in row and row[field]: fullname = row[field] del row[field] break for field in ['firstname', 'first-name', 'given-name', 'fname']: if field in row and row[field]: firstname = row[field] del row[field] break for field in ['lastname', 'last-name', 'surname', 'lname']: if field in row and row[field]: lastname = row[field] del row[field] break for field in ['nickname', 'nick', 'nick-name']: if field in row and row[field]: nickname = row[field] del row[field] break if email.lower() not in existing: recipient = EmailRecipient(campaign=campaign, email=email.lower(), fullname=fullname, firstname=firstname, lastname=lastname, nickname=nickname) recipient.data = {} for key in row: recipient.data[key] = row[key].strip() fields.add(key) db.session.add(recipient) existing.add(recipient.email.lower()) campaign.fields = fields
def proposal_new(space): form = ProposalForm(model=Proposal, parent=space) del form.session_type # We don't use this anymore form.section.query = ProposalSpaceSection.query.filter_by( proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email form.phone.data = g.user.phone if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) if form.speaking.data: proposal.speaker = g.user else: proposal.speaker = None proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal) proposal.name = make_name(proposal.title) db.session.add(proposal) db.session.commit() flash(_("Your new session has been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_template( 'baseframe/autoform.html', form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), breadcrumbs=[(space.url_for(), space.title)], message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' )))
def get_rsvp_state_csv(self, state): outfile = io.StringIO() out = csv.writer(outfile) out.writerow(['fullname', 'email', 'created_at']) for rsvp in self.obj.rsvps_with(state): out.writerow([ rsvp.user.fullname, (rsvp.user.email if rsvp.user.email else rsvp.user.emailclaims[0] if rsvp.user.emailclaims else ''), rsvp.created_at.astimezone(self.obj.timezone).replace( second=0, microsecond=0, tzinfo=None).isoformat(), # Strip precision from timestamp ]) outfile.seek(0) return Response( outfile.getvalue(), content_type='text/csv', headers=[( 'Content-Disposition', 'attachment;filename="{filename}.csv"'.format( filename='ticket-participants-{project}-{state}'.format( project=make_name(self.obj.title), state=state)), )], )
def proposal_new(profile, space): form = ProposalForm(model=Proposal, parent=space) del form.session_type # We don't use this anymore form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by("title") if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == "GET": form.email.data = g.user.email form.phone.data = g.user.phone if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) with db.session.no_autoflush: proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal.formdata) proposal.name = make_name(proposal.title) db.session.add(proposal) db.session.commit() flash(_("Your new session has been saved"), "info") return redirect(proposal.url_for(), code=303) return render_form( form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.') ), )
def get_orders(self): self.browser.open(URI['orders'].format(event_id=self.event_id)) csv_data = self.browser.response().read() f = StringIO.StringIO(csv_data) headers = [make_name(field).replace(u'-', u'').replace(u'\n', u'') for field in f.next().split(',')] orders = unicodecsv.reader(f, delimiter=',') def indexof(name): try: return headers.index(name) except ValueError: return None columns = dict( ticket_number=indexof(u'ticketnumber'), name=indexof(u'name'), email=indexof(u'email'), company=indexof(u'company'), job=indexof(u'jobtitle'), city=indexof(u'city'), phone=indexof(u'phone'), twitter=indexof(u'twitterhandle'), regdate=indexof(u'date'), order_id=indexof(u'orderid'), ticket_type=indexof(u'ticketname'), addons=indexof(u'addonspurchased'), discount=indexof(u'discountcode') ) orders = [{column:order[columns[column]] for column in columns if columns[column]} for order in orders] for order in orders: order['order_url'] = URI['order'].format(event_id=self.event_id, order_id=order['order_id']) return orders
def proposal_edit(profile, space, proposal): form = ProposalForm(obj=proposal.formdata, model=Proposal, parent=space) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type if space.inherit_sections: form.section.query = ProposalSpaceSection.query.filter( or_(ProposalSpaceSection.proposal_space == space, ProposalSpaceSection.proposal_space == space.parent_space), ProposalSpaceSection.public == True).order_by('title') else: form.section.query = ProposalSpaceSection.query.filter( ProposalSpaceSection.proposal_space == space, ProposalSpaceSection.public == True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if proposal.user != g.user: del form.speaking if form.validate_on_submit(): form.populate_obj(proposal.formdata) proposal.name = make_name(proposal.title) proposal.edited_at = datetime.utcnow() db.session.commit() flash(_("Your changes have been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_form( form=form, title=_("Edit session proposal"), submit=_("Save changes"), message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' )))
def get(cls, tag, create=False): title = tag[:cls.__name_length__] name = make_name(title) ob = cls.query.filter_by(name=name).one_or_none() if create and not ob: ob = cls(name=name, title=title) ob = failsafe_add(db.session, ob, name=name) return ob
def label_doesnt_exist(form, field): profile_id = form.profile_id.data label_name = make_name(field.data) if label_name in reserved_words(): raise ValidationError('"%s" is reserved and cannot be used as a label. Please try another name.' % label_name) exists = Label.query.filter_by(profile_id=profile_id, name=label_name).first() if exists: raise ValidationError('Label "%s" already exists. Please try another name.' % field.data)
def asset_key(assets: List[str]) -> str: """Convert multiple version specs into a URL-friendly key.""" return make_name( '-'.join(assets) .replace('==', '-eq-') .replace('>=', '-gte-') .replace('<=', '-lte-') .replace('>', '-gt-') .replace('<', '-lt-'), maxlength=250, )
def make_name(self, reserved=[]): if self.ascii_title: usetitle = self.use_title if self.id: def checkused(c): return bool(c in reserved or GeoName.query.filter(GeoName.id != self.id).filter_by(name=c).notempty()) else: def checkused(c): return bool(c in reserved or GeoName.query.filter_by(name=c).notempty()) with db.session.no_autoflush: self.name = unicode(make_name(usetitle, maxlength=250, checkused=checkused))
def project_csv(self, uuid_b58): """Contacts for a given project in CSV format""" archived = getbool(request.args.get('archived')) project = self.get_project(uuid_b58) contacts = ContactExchange.contacts_for_project( current_auth.user, project, archived) return self.contacts_to_csv( contacts, timezone=project.timezone, filename='contacts-{project}'.format( project=make_name(project.title)), )
def csv(self): if self.obj.type not in ('Y', 'N', 'M', 'F'): abort(403) outfile = StringIO() out = csv.writer(outfile, 'excel') out.writerow(['fullname', 'username', 'email', 'phone']) for ua in self.obj.useractions: out.writerow([ ua.user.fullname, ua.user.username, ua.user.email, ua.user.phone ]) return ( outfile.getvalue(), 200, { 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="%s-%s.csv"' % (make_name(self.obj.parent.title), make_name(self.obj.title)), }, )
def edit(self): form = ProposalForm(obj=self.obj, model=Proposal, parent=self.obj.project) if self.obj.user != g.user: del form.speaking if form.validate_on_submit(): form.populate_obj(self.obj) self.obj.name = make_name(self.obj.title) self.obj.edited_at = datetime.utcnow() db.session.commit() flash(_("Your changes have been saved"), 'info') return redirect(self.obj.url_for(), code=303) return render_form(form=form, title=_("Edit session proposal"), submit=_("Update proposal"), message=Markup( _('This form uses <a target="_blank" href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.')))
def get(cls, title): tag = cls.query.filter_by(title=title).first() if tag: return tag else: name = make_name(title) # Is this name already in use? If yes, return it tag = cls.query.filter_by(name=name).first() if tag: return tag else: tag = cls(name=name, title=title) db.session.add(tag) return tag
def editsession(name, slug): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) proposal_id = int(slug.split('-')[0]) proposal = Proposal.query.get(proposal_id) if not proposal: abort(404) if proposal.user != g.user and not lastuser.has_permission('siteadmin'): abort(403) form = ProposalForm(obj=proposal) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True if proposal.user != g.user: del form.speaking elif request.method == 'GET': form.speaking.data = proposal.speaker == g.user if form.validate_on_submit(): form.populate_obj(proposal) proposal.name = make_name(proposal.title) if proposal.user == g.user: # Only allow the speaker to change this status if form.speaking.data: proposal.speaker = g.user else: if proposal.speaker == g.user: proposal.speaker = None # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) proposal.edited_at = datetime.utcnow() db.session.commit() flash("Your changes have been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template('baseframe/autoform.html', form=form, title="Edit session proposal", submit="Save changes", breadcrumbs=[(url_for('viewspace', name=space.name), space.title), (url_for('viewsession', name=space.name, slug=proposal.urlname), proposal.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.'))
def project_date_csv(self, uuid_b58, datestr): """Contacts for a given project and date in CSV format""" archived = getbool(request.args.get('archived')) project = self.get_project(uuid_b58) date = datetime.strptime(datestr, '%Y-%m-%d').date() contacts = ContactExchange.contacts_for_project_and_date( current_auth.user, project, date, archived) return self.contacts_to_csv( contacts, timezone=project.timezone, filename='contacts-{project}-{date}'.format( project=make_name(project.title), date=date.strftime('%Y%m%d')), )
def contact_exchange(event): if request.method == 'GET': return render_template('contact_exchange.html', event=event, debug=str(app.config['DEBUG']).lower(), ui_test=str(request.args.get('ui_test', False)).lower()) if request.method == 'POST': ids = tuple(request.form.getlist('ids[]')) if len(ids) < 2: return jsonify(status=False, error=u'Insufficient users to connect') users = Participant.query.filter(Participant.event_id == event.id, Participant.nfc_id.in_(ids)).all() mail = Mail(app) message = Message("You connected with " + str(len(users) - 1) + " people using ContactExchange") message.cc = list() for user in users: email = '"' + user.name + '"<' + user.email + '>' if message.reply_to is None: message.reply_to = email message.add_recipient(email) else: message.cc.append(email) message.attach( make_name(user.name) + '.vcf', 'text/vcard', render_template('user_card.vcf', user=user, event=event)) message.sender = '"HasGeek"<*****@*****.**>' message.body = render_template('connectemail.md', users=users, event=event) message.html = markdown(message.body) log = CXLog() try: mail.send(message) log.sent = True log.log_message = u"Mail delivered to postfix server" except Exception as error: log.sent = True log.log_message = unicode(error) log.users = u','.join(ids) db.session.add(log) db.session.commit() return jsonify(success=True)
def test_unlimited_coupon_kharcha(client, all_data): first_item = Item.query.filter_by(name='conference-ticket').first() coupon_code = 'unlimited' discounted_quantity = 5 kharcha_req = { 'line_items': [ {'item_id': str(first_item.id), 'quantity': discounted_quantity} ], 'discount_coupons': [coupon_code], } resp = client.post( url_for('kharcha'), data=json.dumps(kharcha_req), content_type='application/json', headers=[ ('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL']), ], ) resp_json = json.loads(resp.get_data()) assert resp.status_code == 200 base_amount = discounted_quantity * first_item.current_price().amount discount_policy = DiscountPolicy.query.filter_by( name=make_name('Unlimited Geek') ).one() discounted_amount = discounted_quantity * ( (discount_policy.percentage / decimal.Decimal('100')) * first_item.current_price().amount ) assert ( resp_json.get('line_items')[str(first_item.id)].get('final_amount') == base_amount - discounted_amount ) policy_ids = [ str(policy) for policy in resp_json.get('line_items')[str(first_item.id)].get( 'discount_policy_ids' ) ] expected_discount_policy_ids = [discount_policy.id] # Test that all the discount policies are returned for expected_policy_id in expected_discount_policy_ids: assert str(expected_policy_id) in policy_ids
def new_update(self): form = UpdateForm() if form.validate_on_submit(): update = Update(user=current_auth.user, project=self.obj) form.populate_obj(update) update.name = make_name(update.title) db.session.add(update) db.session.commit() return redirect(update.url_for(), code=303) return render_form( form=form, title=_("Post an update"), submit=_("Save & preview"), cancel_url=self.obj.url_for('updates'), )
def export_kiosk(kiosk): participants = StringIO() fieldnames= ['Name', 'Email','Company', 'Job', 'Phone', 'City'] writer = csv.DictWriter(participants, fieldnames=fieldnames) writer.writeheader() for participant in kiosk.participants: writer.writerow({"Name":participant.name, "Email": participant.email, "Company": participant.company, "Job": participant.job, "Phone": participant.phone, "City": participant.city }) response = make_response(participants.getvalue()) response.headers['Content-Type'] = 'text/csv; charset=utf-8' response.headers['Content-Disposition'] = 'attachment; filename=%s.csv' % make_name(kiosk.name) return response
def new_proposal(self): form = ProposalForm(model=Proposal, parent=self.obj) if request.method == 'GET': form.email.data = g.user.email form.phone.data = g.user.phone if form.validate_on_submit(): proposal = Proposal(user=current_auth.user, project=self.obj) form.populate_obj(proposal) proposal.name = make_name(proposal.title) db.session.add(proposal) proposal.voteset.vote(g.user) # Vote up your own proposal by default db.session.commit() flash(_("Your new session has been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_form(form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), message=Markup( _('This form uses <a target="_blank" href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.')))
def make_name(self, reserved=[]): if self.ascii_title: usetitle = self.ascii_title if self.fclass == u'A' and self.fcode.startswith(u'PCL'): if u'of the' in usetitle: usetitle = usetitle.split(u'of the')[-1].strip() elif u'of The' in usetitle: usetitle = usetitle.split(u'of The')[-1].strip() elif u'of' in usetitle: usetitle = usetitle.split(u'of')[-1].strip() elif self.fclass == u'A' and self.fcode == 'ADM1': usetitle = usetitle.replace(u'State of', '').replace(u'Union Territory of', '').strip() if self.id: checkused = lambda c: bool(c in reserved or GeoName.query.filter(GeoName.id != self.id).filter_by(name=c).count()) else: checkused = lambda c: bool(c in reserved or GeoName.query.filter_by(name=c).count()) self.name = make_name(usetitle, maxlength=250, checkused=checkused)
def export_kiosk(kiosk): participants = StringIO() fieldnames = ['Name', 'Email', 'Company', 'Job', 'Phone', 'City'] writer = csv.DictWriter(participants, fieldnames=fieldnames) writer.writeheader() for participant in kiosk.participants: writer.writerow({ "Name": participant.name, "Email": participant.email, "Company": participant.company, "Job": participant.job, "Phone": participant.phone, "City": participant.city }) response = make_response(participants.getvalue()) response.headers['Content-Type'] = 'text/csv; charset=utf-8' response.headers[ 'Content-Disposition'] = 'attachment; filename=%s.csv' % make_name( kiosk.name) return response
def newsession(name): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) if space.status != SPACESTATUS.SUBMISSIONS: abort(403) form = ProposalForm() del form.session_type # We don't use this anymore # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) if form.speaking.data: proposal.speaker = g.user else: proposal.speaker = None proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal) proposal.name = make_name(proposal.title) # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) db.session.add(proposal) db.session.commit() flash("Your new session has been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template('baseframe/autoform.html', form=form, title="Submit a session proposal", submit="Submit session", breadcrumbs=[(url_for('viewspace', name=space.name), space.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.'))
def proposal_edit(space, proposal): if lastuser.has_permission('siteadmin'): form = ProposalFormForAdmin(obj=proposal, model=Proposal, parent=space) else: form = ProposalForm(obj=proposal, model=Proposal, parent=space) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by( proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if proposal.user != g.user: del form.speaking elif request.method == 'GET': form.speaking.data = proposal.speaker == g.user if form.validate_on_submit(): form.populate_obj(proposal) proposal.name = make_name(proposal.title) if proposal.user == g.user: # Only allow the speaker to change this status if form.speaking.data: proposal.speaker = g.user else: if proposal.speaker == g.user: proposal.speaker = None proposal.edited_at = datetime.utcnow() db.session.commit() flash(_("Your changes have been saved"), 'info') return redirect(proposal.url_for(), code=303) return render_template( 'baseframe/autoform.html', form=form, title=_("Edit session proposal"), submit=_("Save changes"), breadcrumbs=[(space.url_for(), space.title), (proposal.url_for(), proposal.title)], message=Markup( _('This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' )))
def edit(self): form = ProposalForm(obj=self.obj, model=Proposal, parent=self.obj.project) if self.obj.user != current_auth.user: del form.speaking if form.validate_on_submit(): with db.session.no_autoflush: form.populate_obj(self.obj) self.obj.name = make_name(self.obj.title) self.obj.edited_at = db.func.utcnow() db.session.commit() flash(_("Your changes have been saved"), 'info') return redirect(self.obj.url_for(), code=303) return render_form( form=form, title=_("Edit session proposal"), submit=_("Update proposal"), message=Markup( _('This form uses <a target="_blank" rel="noopener noreferrer" href="https://www.markdownguide.org/basic-syntax/">Markdown</a> for formatting.' )), )
def make_name(self, reserved=[]): if self.ascii_title: usetitle = self.ascii_title if self.fclass == u'A' and self.fcode.startswith(u'PCL'): if u'of the' in usetitle: usetitle = usetitle.split(u'of the')[-1].strip() elif u'of The' in usetitle: usetitle = usetitle.split(u'of The')[-1].strip() elif u'of' in usetitle: usetitle = usetitle.split(u'of')[-1].strip() elif self.fclass == u'A' and self.fcode == 'ADM1': usetitle = usetitle.replace(u'State of', '').replace( u'Union Territory of', '').strip() if self.id: checkused = lambda c: bool(c in reserved or GeoName.query. filter(GeoName.id != self.id ).filter_by(name=c).count()) else: checkused = lambda c: bool(c in reserved or GeoName.query. filter_by(name=c).count()) self.name = make_name(usetitle, maxlength=250, checkused=checkused)
def new_proposal(self): # This along with the `reader` role makes it possible for # anyone to submit a proposal if the CFP is open. if not self.obj.cfp_state.OPEN: flash(_("CFP for this project is not open"), 'error') return redirect(self.obj.url_for(), code=303) form = ProposalForm(model=Proposal, parent=self.obj) if request.method == 'GET': form.email.data = str(current_auth.user.email) form.phone.data = str(current_auth.user.phone) if form.validate_on_submit(): proposal = Proposal(user=current_auth.user, project=self.obj) db.session.add(proposal) with db.session.no_autoflush: form.populate_obj(proposal) proposal.name = make_name(proposal.title) proposal.voteset.vote( current_auth.user) # Vote up your own proposal by default db.session.commit() flash(_("Your new session proposal has been submitted"), 'info') dispatch_notification( ProposalSubmittedNotification(document=proposal), ProposalReceivedNotification(document=proposal.project, fragment=proposal), ) return redirect(proposal.url_for(), code=303) return render_form( form=form, title=_("Submit a session proposal"), submit=_("Submit proposal"), message=Markup( _('This form uses <a target="_blank" rel="noopener noreferrer" href="https://www.markdownguide.org/basic-syntax/">Markdown</a> for formatting.' )), )
def test_unlimited_coupon_kharcha(self): first_item = Item.query.filter_by(name='conference-ticket').first() coupon_code = 'unlimited' discounted_quantity = 5 kharcha_req = {'line_items': [{ 'item_id': unicode(first_item.id), 'quantity': discounted_quantity }], 'discount_coupons': [coupon_code]} resp = self.client.post(url_for('kharcha'), data=json.dumps(kharcha_req), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) resp_json = json.loads(resp.get_data()) self.assertEquals(resp.status_code, 200) base_amount = discounted_quantity * first_item.current_price().amount discount_policy = DiscountPolicy.query.filter_by(name=make_name('Unlimited Geek')).one() discounted_amount = discounted_quantity * ((discount_policy.percentage/decimal.Decimal('100')) * first_item.current_price().amount) self.assertEquals(resp_json.get('line_items')[unicode(first_item.id)].get('final_amount'), base_amount - discounted_amount) policy_ids = [unicode(policy) for policy in resp_json.get('line_items')[unicode(first_item.id)].get('discount_policy_ids')] expected_discount_policy_ids = [discount_policy.id] # Test that all the discount policies are returned for expected_policy_id in expected_discount_policy_ids: self.assertIn(unicode(expected_policy_id), [policy for policy in policy_ids])
def contact_exchange(event): if request.method=='GET': return render_template('contact_exchange.html.jinja2', event=event, debug=str(app.config['DEBUG']).lower(), ui_test=str(request.args.get('ui_test', False)).lower()) if request.method == 'POST': ids = tuple(request.form.getlist('ids[]')) if len(ids) < 2: return jsonify(status=False, error=u'Insufficient users to connect') users = Participant.query.filter(Participant.event_id == event.id, Participant.nfc_id.in_(ids)).all() mail = Mail(app) message = Message("You connected with " + str(len(users) - 1) + " people using ContactExchange") message.cc = list() for user in users: email = '"' + user.name + '"<' + user.email + '>' if message.reply_to is None: message.reply_to = email message.add_recipient(email) else: message.cc.append(email) message.attach(make_name(user.name) + '.vcf', 'text/vcard', render_template('user_card.vcf', user=user, event=event)) message.sender = '"HasGeek"<*****@*****.**>' message.body = render_template('connectemail.md', users=users, event=event) message.html = markdown(message.body) log = CXLog() try: mail.send(message) log.sent = True log.log_message = u"Mail delivered to postfix server" except Exception as error: log.sent = True log.log_message = unicode(error) log.users = u','.join(ids) db.session.add(log) db.session.commit() return jsonify(success=True)
def asset_key(assets): return make_name('-'.join(assets).replace('==', '-eq-').replace( '>=', '-gte-').replace('<=', '-lte-').replace('>', '-gt-').replace('<', '-lt-'), maxlength=250)
def autocomplete(cls, prefix): search = make_name(prefix) + '%' return cls.query.filter(cls.name.like(search), cls.public == True).all() # NOQA
def update_from_user(cls, user, session, parent=None, type_user=None, type_org=None, type_col='type', make_user_profiles=True, make_org_profiles=True): """ Update profiles from the given user and user's organizations. :param user: User account with organization data. :param session: Database session (typically db.session). :param parent: Parent object, if applicable. :param type_user: Type value for user profiles, if applicable. :param type_org: Type value for organization profiles, if applicable. :param unicode type_col: Column for type value, if applicable. :param bool make_user_profiles: Should user profiles be created? :param bool make_org_profiles: Should organization profiles be created? """ idsnames = { user.userid: { 'name': user.profile_name, 'title': user.fullname, 'domain': None } } for org in user.organizations_memberof(): idsnames[org['userid']] = { 'name': org['name'], 'title': org['title'], 'domain': org.get('domain') } namesids = dict([(value['name'], key) for key, value in idsnames.items()]) # First, check if Profile userids and names match for profile in cls.query.filter(cls.name.in_(namesids.keys())).all(): if profile.userid != namesids[profile.name]: # This profile's userid and name don't match. Knock off the name profile.name = make_name(profile.userid, maxlength=250, checkused=lambda c: True if session.query(cls.name).filter_by( name=c).first() else False) # Flush this to the db for constraint integrity session.flush() # Second, check the other way around and keep this list of profiles profiles = dict([ (p.userid, p) for p in cls.query.filter(cls.userid.in_(idsnames.keys())).all() ]) for profile in profiles.values(): if profile.name != idsnames[profile.userid]['name']: profile.name = idsnames[profile.userid]['name'] if profile.title != idsnames[profile.userid]['title']: profile.title = idsnames[profile.userid]['title'] if hasattr(profile, 'domain' ): # If this profile has a domain attribute, set it if profile.domain != idsnames[profile.userid]['domain']: profile.domain = idsnames[profile.userid]['domain'] # Flush this too session.flush() # Third, make new profiles if required if make_user_profiles: if user.userid not in profiles: if parent is not None: profile = cls(userid=user.userid, name=user.profile_name, title=user.fullname, parent=parent) else: profile = cls(userid=user.userid, name=user.profile_name, title=user.fullname) if type_user is not None: setattr(profile, type_col, type_user) session.add(profile) if make_org_profiles: for org in user.organizations_memberof(): if org['userid'] not in profiles: if parent is not None: profile = cls(userid=org['userid'], name=org['name'], title=org['title'], parent=parent) else: profile = cls(userid=org['userid'], name=org['name'], title=org['title']) if type_org is not None: setattr(profile, type_col, type_org) if org.get('domain'): profile.domain = org['domain'] session.add(profile) # Fourth, migrate profiles if there are any matching the user's old ids if user.oldids: profile = cls.query.filter_by(userid=user.userid).first() if profile: oldprofiles = cls.query.filter(cls.userid.in_( user.oldids)).all() for op in oldprofiles: op.merge_into(profile)
def asset_key(assets): return make_name('-'.join(assets).replace( '==', '-eq-').replace('>=', '-gte-').replace('<=', '-lte-').replace('>', '-gt-').replace('<', '-lt-'), maxlength=250)
def sync_event(event): syncform = EventSyncForm() if request.method == 'GET' or not syncform.validate_on_submit(): return render_template('form.html', form=syncform, title=u"Sync", submit=u"Sync Now") else: browser = Browser(factory=RobustFactory()) speakers = [] speakers_fetched = False lastuser_loggedin = False eventframe_data = None ret = [] if (event.funnel_space or event.eventframe_sync) and request.form.get( 'lastuser_username', None) and request.form.get( 'lastuser_password', None): browser.open("https://auth.hasgeek.com/login") browser.select_form(nr=1) form = browser.form form['username'] = request.form.get('lastuser_username') form['password'] = request.form.get('lastuser_password') browser.open(form.click()) if browser.geturl() == "https://auth.hasgeek.com/login": flash("Problem logging into LastUser", "danger") return render_template('form.html', form=EventSyncForm(), title=u"Sync", submit=u"Sync Now") else: lastuser_loggedin = True if lastuser_loggedin and event.funnel_space: browser.open("https://funnel.hasgeek.com/login") ret.append("Fetching speakers") browser.open("https://funnel.hasgeek.com/{space}/json".format( space=event.funnel_space)) funnel_data = json.loads(browser.response().read()) for proposal in funnel_data['proposals']: if proposal['confirmed']: proposal['speaker'] = unicode(proposal['speaker']) if u'(' in proposal['speaker']: proposal['speaker'] = u'('.join( proposal['speaker'].split( '(')[:-1]).strip().title() speakers.append( (proposal['speaker'], proposal['email'])) speakers = list(set(speakers)) speakers_fetched = True ret.append("There are %s speakers" % len(speakers)) ret.append("Syncing venues from Funnel") try: names = [venue['name'] for venue in funnel_data['venues']] for venue in Venue.query.filter_by( event=event, from_funnel=True).filter( ~Venue.name.in_(names)).all(): for activity in venue.activity: db.session.delete(activity) db.session.delete(venue) db.session.commit() ret.append("Deleted removed venues") except Exception as e: ret.append("Error deleting removed venues: %s" % str(e)) venues = dict() for venue in funnel_data['venues']: try: venues[venue['name']] = Venue.query.filter_by( name=venue['name'], event=event, from_funnel=True).one() ret.append( "Venue %s exists as %s" % (venue['title'], venues[venue['name']].title)) except NoResultFound: try: venues[venue['name']] = Venue(event=event, name=venue['name'], title=venue['title'], from_funnel=True) db.session.add(venues[venue['name']]) db.session.commit() ret.append("Added venue %s" % venue['title']) except Exception as e: ret.append("Error adding venue %s: %s" % (venue['title'], str(e))) for room in funnel_data['rooms']: venues[room['name']] = venues[room['venue']] activity = defaultdict(list) for day_number, day in enumerate(funnel_data['schedule']): for slot in day['slots']: for session in slot['sessions']: if session['room'] and session['room'] in venues: if (day_number, day['date'] ) not in activity[session['room']]: activity[session['room']].append( (day_number, day['date'])) for venue, days in activity.iteritems(): try: dates = [date for (day_number, date) in days] Activity.query.filter_by( venue=venues[venue], from_funnel=True).filter( ~Activity.date.in_(dates)).delete( synchronize_session=False) ret.append("Deleted removed activity days for %s" % venues[venue].title) except Exception as e: ret.append( "Error deleting removed activity days for %s: %s" % (venues[venue].title, str(e))) for day_number, date in days: try: item = Activity.query.filter_by( venue=venues[venue], date=date, from_funnel=True).one() ret.append("Activity on %s exists as %s" % (item.date, item.title)) except NoResultFound: try: item = Activity( venue=venues[venue], date=date, title="Day %s - %s" % (day_number + 1, venues[venue].title), from_funnel=True) db.session.add(item) db.session.commit() ret.append("Added activity: %s on %s" % (item.title, item.date)) except Exception as e: ret.append( "Error adding activity %s: %s" % ("Day %s - %s" % (day_number + 1, venues[venue].title), str(e))) ret.append("Funnel sync complete") if lastuser_loggedin and event.eventframe_sync: ret.append("Fetching data from Eventframe") browser.open("https://eventframe.hasgeek.com/login") browser.open(event.eventframe_sync) eventframe_data = json.loads( browser.response().read())['attendees'] ret.append("Fetched %s people from Eventframe" % len(eventframe_data)) added = [0] failed = [] updated = [0] deleted = 0 if app.config['DOATTEND_EMAIL'] in [ None, '' ] or app.config['DOATTEND_PASS'] in [ None, '' ] or event.doattend_id in [None, '']: ret.append('DoAttend details not available') else: uri = 'http://doattend.com/' browser.open(urljoin(uri, 'accounts/sign_in')) browser.select_form(nr=0) form = browser.form form['account[email]'] = app.config['DOATTEND_EMAIL'] form['account[password]'] = app.config['DOATTEND_PASS'] browser.open(form.click()) if browser.geturl() == urljoin(uri, 'accounts/sign_in'): ret.append('DoAttend Login Failed') else: ret.append('Syncing tickets') tickets = [] browser.open( urljoin(uri, 'events/' + event.doattend_id + '/tickets')) resp = html.fromstring(browser.response().read()) tickets_list = resp.get_element_by_id('tickets_list') tickets_list = tickets_list.cssselect('.list') ticket_ids = [] for ticket in tickets_list: tickets.append({ 'id': ticket.attrib['id'].split('_')[1], 'name': ticket.cssselect('div:nth-child(2) h3') [0].text.strip() }) ticket_ids.append(ticket.attrib['id'].split('_')[1]) tickets_list = resp.cssselect('#tickets_list')[1] tickets_list = tickets_list.cssselect('.list') for ticket in tickets_list: tickets.append({ 'id': ticket.attrib['id'].split('_')[1], 'name': ticket.cssselect('div:nth-child(2) h3') [0].text.strip() }) ticket_ids.append(ticket.attrib['id'].split('_')[1]) try: ret.append('Deleting removed tickets') Product.query.filter_by( event=event, source='doattend').filter( ~Product.id.in_(ticket_ids)).delete( synchronize_session=False) db.session.commit() ret.append('Removed tickets deleted') except Exception as e: ret.append("Error deleting removed tickets: %s" % str(e)) for ticket in tickets: try: t = Product.query.filter_by(id_source=ticket['id'], event=event, source='doattend').one() ret.append("Ticket %s(%s) exists as %s" % (ticket['name'], ticket['id'], t.title)) except NoResultFound: try: t = Product(id_source=ticket['id'], event=event, title=ticket['name'], source='doattend') t.make_name() db.session.add(t) db.session.commit() ret.append("Added ticket %s(%s)" % (ticket['name'], ticket['id'])) except Exception as e: ret.append("Error adding ticket %s: %s" % (ticket['name'], str(e))) db.session.commit() browser.open( urljoin( uri, 'events/' + event.doattend_id + '/orders/registration_sheet.csv')) csv_data = browser.response().read() browser.open( urljoin( uri, 'events/' + event.doattend_id + '/orders/confirmed_guests.csv')) guests_csv = browser.response().read() browser.open(urljoin(uri, 'accounts/sign_out')) tickets = [] f = StringIO.StringIO(csv_data) headers = [ make_name(field).replace(u'-', u'').replace(u'\n', u'') for field in f.next().split(',') ] users = unicodecsv.reader(f, delimiter=',') ret.append("Starting Participants") def process_ticket(user): user[columns['name']] = user[columns['name']].title() participant = Participant.query.filter_by( ticket_number=user[columns['ticket_number']].strip(), event_id=event.id, online_reg=True).first() if not participant: for p in Participant.query.filter_by( email=user[columns['email']].strip(), event_id=event.id).all(): if levenshtein(p.name, user[columns['name']].strip()) <= 3: participant = p break elif participant.email != user[columns['email']]: participant.image = 'LOAD' if not columns['name'] or user[ columns['name']] == 'Cancelled' or user[ columns['name']] == 'Not Attending': return new = participant is None if new: participant = Participant() participant.event_id = event.id participant.purchases = [] participant.image = 'LOAD' else: if participant.purchases is None: participant.purchases = [] else: participant.purchases = participant.purchases.split( ', ') if 'order_id' in columns and columns['order_id'] and user[ columns['order_id']]: user[columns['order_id']] = int( user[columns['order_id']]) if columns['twitter'] and user[columns[ 'twitter']] and '@' in user[columns['twitter']]: user[columns['twitter']] = user[ columns['twitter']].strip().replace('@', '').strip() if columns['phone'] and user[columns['phone']]: user[columns['phone']] = user[ columns['phone']].strip().replace(' ', '').replace( '-', '') for field in columns.keys(): if columns[field]: value = user[columns[field]] if type(value) == unicode: value = value.strip() value = None if value == '*' or value == '' or value == 'empty' else value if (new or (field != 'ticket_number' and getattr(participant, field)) ) and value != getattr(participant, field): setattr(participant, field, value) if speakers_fetched and participant.speaker and ( participant.name, participant.email) not in speakers: participant.speaker = False if (participant.name, participant.email) in speakers: participant.speaker = True if user[others['ticket_type']]: participant.purchases.append( user[others['ticket_type']].strip()) if 'addons' in others and others['addons'] and user[ others['addons']]: participant.purchases = participant.purchases + ( user[others['addons']]).strip().split(',') for i, purchase in enumerate(participant.purchases): participant.purchases[i] = purchase.strip().replace( u'Apr 18 - 19', u'May 16 - 17').replace(u'Apr 16 - 17', u'May 14 - 15').replace( u'Apr 16 - 19', u'May 14 - 17') if u"T-shirt" in participant.purchases or u"Corporate" in participant.purchases: participant.purchased_tee = True participant.purchases = ', '.join( list(set(participant.purchases))) participant.online_reg = True if participant.ticket_number: tickets.append(participant.ticket_number) try: if new: db.session.add(participant) db.session.commit() if new: added[0] = added[0] + 1 ret.append("Added " + participant.name.encode('utf-8')) else: updated[0] = updated[0] + 1 ret.append("Updated " + participant.name.encode('utf-8')) except Exception as e: ret.append("Error adding/updating " + participant.name.encode('utf-8') + ': ' + str(e)) failed.append( participant.name.encode('utf-8') + '(' + participant.email.encode('utf-8') + '): ' + str(e)) db.session.rollback() def indexof(name): try: return headers.index(name) except ValueError: return None columns = dict(ticket_number=indexof(u'ticketnumber'), name=indexof(u'name'), email=indexof(u'email'), company=indexof(u'company'), job=indexof(u'jobtitle'), city=indexof(u'city'), phone=indexof(u'phone'), twitter=indexof(u'twitterhandle'), regdate=indexof(u'date'), order_id=indexof(u'orderid')) others = dict(ticket_type=indexof(u'ticketname'), addons=indexof(u'addonspurchased')) for user in users: process_ticket(user) ret.append("Done with Participants") ret.append("Starting Guests") f = StringIO.StringIO(guests_csv) headers = [ make_name(field).replace(u'-', u'').replace(u'\n', u'') for field in f.next().split(',') ] users = unicodecsv.reader(f, delimiter=',') columns = dict(ticket_number=indexof(u'ticketnumber'), name=indexof(u'name'), email=indexof(u'email'), company=indexof(u'company'), job=indexof(u'jobtitle'), city=indexof(u'city'), phone=indexof(u'phone'), twitter=indexof(u'twitterhandle'), regdate=indexof(u'confirmedon')) others = dict(ticket_type=indexof(u'ticket')) for user in users: process_ticket(user) ret.append("Done with Guests") if eventframe_data: ret.append("Starting Eventframe RSVP data") columns = dict(ticket_number='ticket', name='ticket_name', email='ticket_email', phone='ticket_phone', company='ticket_company', job='ticket_jobtitle', city='ticket_city', twitter='ticket_twitter') others = dict(ticket_type='ticket_type') for user in eventframe_data: if user['status'] == "Y" and 'ticket' in user: process_ticket(user) ret.append("Done with RSVPs") ret.append("Removing deleted tickets") participants = Participant.query.filter( ~Participant.ticket_number.in_(tickets), Participant.online_reg == True, Participant.event_id == event.id).all() for participant in participants: try: db.session.delete(participant) db.session.commit() deleted = deleted + 1 ret.append("Delete: " + participant.name.encode('utf-8')) except Exception as e: ret.append("Error deleting " + participant.name.encode('utf-8') + ':' + e) ret.append("Deleting complete") for participant in Participant.query.filter_by(event=event, image='LOAD').all(): ret.append("Loading gravatar image for %s" % (participant.email)) try: response = requests.get( "http://www.gravatar.com/avatar/" + md5(participant.email.lower()).hexdigest(), params={ 'd': '404', 's': '400' }) if response.status_code == 404: participant.image = None ret.append('Image not present') else: participant.image = b64encode(response.content) ret.append('Image loaded: %s' % participant.image) db.session.commit() except Exception as e: ret.append('Error: ' + str(e)) return json.dumps( dict(added=added[0], updated=updated[0], deleted=deleted, failed=failed, trace=ret))
def __call__(self, form, field): if make_name(field.data) != field.data: raise StopValidation(self.message)
def __call__(self, form, field): if make_name(field.data) != field.data: raise wtforms.validators.StopValidation(self.message)
def update_from_user(cls, user, session, parent=None, type_user=None, type_org=None, type_col='type', make_user_profiles=True, make_org_profiles=True): """ Update profiles from the given user and user's organizations. :param user: User account with organization data. :param session: Database session (typically db.session). :param parent: Parent object, if applicable. :param type_user: Type value for user profiles, if applicable. :param type_org: Type value for organization profiles, if applicable. :param unicode type_col: Column for type value, if applicable. :param bool make_user_profiles: Should user profiles be created? :param bool make_org_profiles: Should organization profiles be created? """ idsnames = {user.userid: {'name': user.profile_name, 'title': user.fullname, 'domain': None}} for org in user.organizations_memberof(): idsnames[org['userid']] = {'name': org['name'], 'title': org['title'], 'domain': org.get('domain')} namesids = dict([(value['name'], key) for key, value in idsnames.items()]) # First, check if Profile userids and names match for profile in cls.query.filter(cls.name.in_(namesids.keys())).all(): if profile.userid != namesids[profile.name]: # This profile's userid and name don't match. Knock off the name profile.name = make_name(profile.userid, maxlength=250, checkused=lambda c: True if session.query(cls.name).filter_by(name=c).first() else False) # Flush this to the db for constraint integrity session.flush() # Second, check the other way around and keep this list of profiles profiles = dict([(p.userid, p) for p in cls.query.filter(cls.userid.in_(idsnames.keys())).all()]) for profile in profiles.values(): if profile.name != idsnames[profile.userid]['name']: profile.name = idsnames[profile.userid]['name'] if profile.title != idsnames[profile.userid]['title']: profile.title = idsnames[profile.userid]['title'] if hasattr(profile, 'domain'): # If this profile has a domain attribute, set it if profile.domain != idsnames[profile.userid]['domain']: profile.domain = idsnames[profile.userid]['domain'] # Flush this too session.flush() # Third, make new profiles if required if make_user_profiles: if user.userid not in profiles: if parent is not None: profile = cls(userid=user.userid, name=user.profile_name, title=user.fullname, parent=parent) else: profile = cls(userid=user.userid, name=user.profile_name, title=user.fullname) if type_user is not None: setattr(profile, type_col, type_user) session.add(profile) if make_org_profiles: for org in user.organizations_memberof(): if org['userid'] not in profiles: if parent is not None: profile = cls(userid=org['userid'], name=org['name'], title=org['title'], parent=parent) else: profile = cls(userid=org['userid'], name=org['name'], title=org['title']) if type_org is not None: setattr(profile, type_col, type_org) if org.get('domain'): profile.domain = org['domain'] session.add(profile) # Fourth, migrate profiles if there are any matching the user's old ids if user.oldids: profile = cls.query.filter_by(userid=user.userid).first() if profile: oldprofiles = cls.query.filter(cls.userid.in_(user.oldids)).all() for op in oldprofiles: op.merge_into(profile)
def sync_event(event): syncform = EventSyncForm() if request.method == 'GET' or not syncform.validate_on_submit(): return render_template('form.html', form=syncform, title=u"Sync", submit=u"Sync Now") else: browser = Browser(factory=RobustFactory()) speakers = [] speakers_fetched = False lastuser_loggedin = False eventframe_data = None ret = [] if (event.funnel_space or event.eventframe_sync) and request.form.get('lastuser_username', None) and request.form.get('lastuser_password', None): browser.open("https://auth.hasgeek.com/login") browser.select_form(nr=1) form = browser.form form['username'] = request.form.get('lastuser_username') form['password'] = request.form.get('lastuser_password') browser.open(form.click()) if browser.geturl() == "https://auth.hasgeek.com/login": flash("Problem logging into LastUser", "danger") return render_template('form.html', form=EventSyncForm(), title=u"Sync", submit=u"Sync Now") else: lastuser_loggedin = True if lastuser_loggedin and event.funnel_space: browser.open("https://funnel.hasgeek.com/login") ret.append("Fetching speakers") browser.open("https://funnel.hasgeek.com/{space}/json".format(space=event.funnel_space)) funnel_data = json.loads(browser.response().read()) for proposal in funnel_data['proposals']: if proposal['confirmed']: proposal['speaker'] = unicode(proposal['speaker']) if u'(' in proposal['speaker']: proposal['speaker'] = u'('.join(proposal['speaker'].split('(')[:-1]).strip().title() speakers.append((proposal['speaker'], proposal['email'])) speakers = list(set(speakers)) speakers_fetched = True ret.append("There are %s speakers" % len(speakers)) ret.append("Syncing venues from Funnel") try: names = [venue['name'] for venue in funnel_data['venues']] for venue in Venue.query.filter_by(event=event, from_funnel=True).filter(~Venue.name.in_(names)).all(): for activity in venue.activity: db.session.delete(activity) db.session.delete(venue) db.session.commit() ret.append("Deleted removed venues") except Exception as e: ret.append("Error deleting removed venues: %s" % str(e)) venues = dict() for venue in funnel_data['venues']: try: venues[venue['name']] = Venue.query.filter_by(name=venue['name'], event=event, from_funnel=True).one() ret.append("Venue %s exists as %s" % (venue['title'], venues[venue['name']].title)) except NoResultFound: try: venues[venue['name']] = Venue(event=event, name=venue['name'], title=venue['title'], from_funnel=True) db.session.add(venues[venue['name']]) db.session.commit() ret.append("Added venue %s" % venue['title']) except Exception as e: ret.append("Error adding venue %s: %s" % (venue['title'], str(e))) for room in funnel_data['rooms']: venues[room['name']] = venues[room['venue']] activity = defaultdict(list) for day_number, day in enumerate(funnel_data['schedule']): for slot in day['slots']: for session in slot['sessions']: if session['room'] and session['room'] in venues: if (day_number, day['date']) not in activity[session['room']]: activity[session['room']].append((day_number, day['date'])) for venue, days in activity.iteritems(): try: dates = [date for (day_number, date) in days] Activity.query.filter_by(venue=venues[venue], from_funnel=True).filter(~Activity.date.in_(dates)).delete(synchronize_session=False) ret.append("Deleted removed activity days for %s" % venues[venue].title) except Exception as e: ret.append("Error deleting removed activity days for %s: %s" % (venues[venue].title, str(e))) for day_number, date in days: try: item = Activity.query.filter_by(venue=venues[venue], date=date, from_funnel=True).one() ret.append("Activity on %s exists as %s" % (item.date, item.title)) except NoResultFound: try: item = Activity(venue=venues[venue], date=date, title="Day %s - %s" % (day_number + 1, venues[venue].title), from_funnel=True) db.session.add(item) db.session.commit() ret.append("Added activity: %s on %s" % (item.title, item.date)) except Exception as e: ret.append("Error adding activity %s: %s" % ("Day %s - %s" % (day_number + 1, venues[venue].title), str(e))) ret.append("Funnel sync complete") if lastuser_loggedin and event.eventframe_sync: ret.append("Fetching data from Eventframe") browser.open("https://eventframe.hasgeek.com/login") browser.open(event.eventframe_sync) eventframe_data = json.loads(browser.response().read())['attendees'] ret.append("Fetched %s people from Eventframe" % len(eventframe_data)) if app.config['DOATTEND_EMAIL'] in [None, ''] or app.config['DOATTEND_PASS'] in [None, ''] or event.doattend_id in [None, '']: return 'Data not available' uri = 'http://doattend.com/' forms = ParseResponse(urlopen(urljoin(uri, 'accounts/sign_in'))) form = forms[0] form['account[email]'] = app.config['DOATTEND_EMAIL'] form['account[password]'] = app.config['DOATTEND_PASS'] urlopen(form.click()) csv_data = urlopen(urljoin(uri, 'events/' + event.doattend_id + '/orders/registration_sheet.csv')).read() guests_csv = urlopen(urljoin(uri, 'events/' + event.doattend_id + '/orders/confirmed_guests.csv')).read() urlopen(urljoin(uri, 'accounts/sign_out')) f = StringIO.StringIO(csv_data) headers = [make_name(field).replace(u'-', u'').replace(u'\n', u'') for field in f.next().split(',')] users = unicodecsv.reader(f, delimiter=',') added = [0] failed = [] updated = [0] deleted = 0 tickets = [] ret.append("Starting Participants") def process_ticket(user): user[columns['name']] = user[columns['name']].title() participant = Participant.query.filter_by(ticket_number=user[columns['ticket_number']].strip(), event_id=event.id, online_reg=True).first() if not participant: for p in Participant.query.filter_by(email=user[columns['email']].strip(), event_id=event.id).all(): if levenshtein(p.name, user[columns['name']].strip()) <= 3: participant = p break elif participant.email != user[columns['email']]: participant.image = 'LOAD' if not columns['name'] or user[columns['name']] == 'Cancelled': return new = participant is None if new: participant = Participant() participant.event_id = event.id participant.purchases = [] participant.image = 'LOAD' else: if participant.purchases is None: participant.purchases = [] else: participant.purchases = participant.purchases.split(', ') if 'order_id' in columns and columns['order_id'] and user[columns['order_id']]: user[columns['order_id']] = int(user[columns['order_id']]) if columns['twitter'] and user[columns['twitter']] and '@' in user[columns['twitter']]: user[columns['twitter']] = user[columns['twitter']].strip().replace('@', '').strip() if columns['phone'] and user[columns['phone']]: user[columns['phone']] = user[columns['phone']].strip().replace(' ', '').replace('-','') for field in columns.keys(): if columns[field]: value = user[columns[field]] if type(value) == unicode: value = value.strip() value = None if value == '*' or value == '' or value == 'empty' else value if (new or (field != 'ticket_number' and getattr(participant, field))) and value != getattr(participant, field): setattr(participant, field, value) if speakers_fetched and participant.speaker and (participant.name, participant.email) not in speakers: participant.speaker = False if (participant.name, participant.email) in speakers: participant.speaker = True if user[others['ticket_type']]: participant.purchases.append(user[others['ticket_type']].strip()) if 'addons' in others and others['addons'] and user[others['addons']]: participant.purchases = participant.purchases + (user[others['addons']]).strip().split(',') for i, purchase in enumerate(participant.purchases): participant.purchases[i] = purchase.strip().replace(u'Apr 18 - 19', u'May 16 - 17').replace(u'Apr 16 - 17', u'May 14 - 15').replace(u'Apr 16 - 19', u'May 14 - 17') if u"T-shirt" in participant.purchases or u"Corporate" in participant.purchases: participant.purchased_tee = True participant.purchases = ', '.join(list(set(participant.purchases))) participant.online_reg = True if participant.ticket_number: tickets.append(participant.ticket_number) try: if new: db.session.add(participant) db.session.commit() if new: added[0] = added[0] + 1 ret.append("Added " + participant.name.encode('utf-8')) else: updated[0] = updated[0] + 1 ret.append("Updated " + participant.name.encode('utf-8')) except Exception as e: ret.append("Error adding/updating " + participant.name.encode('utf-8') + ': ' + str(e)) failed.append(participant.name.encode('utf-8') + '(' + participant.email.encode('utf-8') + '): ' + str(e)) db.session.rollback() def indexof(name): try: return headers.index(name) except ValueError: return None columns = dict( ticket_number=indexof(u'ticketnumber'), name=indexof(u'name'), email=indexof(u'email'), company=indexof(u'company'), job=indexof(u'jobtitle'), city=indexof(u'city'), phone=indexof(u'phone'), twitter=indexof(u'twitterhandle'), regdate=indexof(u'date'), order_id=indexof(u'orderid') ) others = dict( ticket_type=indexof(u'ticketname'), addons=indexof(u'addonspurchased') ) for user in users: process_ticket(user) ret.append("Done with Participants") ret.append("Starting Guests") f = StringIO.StringIO(guests_csv) headers = [make_name(field).replace(u'-', u'').replace(u'\n', u'') for field in f.next().split(',')] users = unicodecsv.reader(f, delimiter=',') columns = dict( ticket_number=indexof(u'ticketnumber'), name=indexof(u'name'), email=indexof(u'email'), company=indexof(u'company'), job=indexof(u'jobtitle'), city=indexof(u'city'), phone=indexof(u'phone'), twitter=indexof(u'twitterhandle'), regdate=indexof(u'confirmedon') ) others = dict( ticket_type=indexof(u'ticket') ) for user in users: process_ticket(user) ret.append("Done with Guests") if eventframe_data: ret.append("Starting Eventframe RSVP data") columns = dict( ticket_number='ticket', name='ticket_name', email='ticket_email', phone='ticket_phone', company='ticket_company', job='ticket_jobtitle', city='ticket_city', twitter='ticket_twitter' ) others = dict( ticket_type='ticket_type' ) for user in eventframe_data: if user['status'] == "Y" and 'ticket' in user: process_ticket(user) ret.append("Done with RSVPs") ret.append("Removing deleted tickets") participants = Participant.query.filter(~Participant.ticket_number.in_(tickets), Participant.online_reg==True, Participant.event_id==event.id).all() for participant in participants: try: db.session.delete(participant) db.session.commit() deleted = deleted + 1 ret.append("Delete: " + participant.name.encode('utf-8')) except Exception as e: ret.append("Error deleting " + participant.name.encode('utf-8') + ':' + e) ret.append("Deleting complete") for participant in Participant.query.filter_by(event=event, image='LOAD').all(): ret.append("Loading gravatar image for %s" % ( participant.email)) try: response = requests.get( "http://www.gravatar.com/avatar/" + md5(participant.email.lower()).hexdigest(), params={'d': '404', 's': '400'}) if response.status_code == 404: participant.image = None ret.append('Image not present') else: participant.image = b64encode(response.content) ret.append('Image loaded: %s' % participant.image) db.session.commit() except Exception as e: ret.append('Error: ' + str(e)) return json.dumps(dict( added=added[0], updated=updated[0], deleted=deleted, failed=failed, trace=ret ))
def autocomplete(cls, prefix): search = escape_for_sql_like(make_name(prefix)) return cls.query.filter(cls.name.like(search), cls.public == True).all() # NOQA
def autocomplete(cls, prefix): search = escape_for_sql_like(make_name(prefix)) return cls.query.filter(cls.name.like(search), cls.public.is_(True)).all()
def valid_name(form, field): field.data = make_name(field.data)