Exemple #1
0
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))}
Exemple #2
0
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))}
Exemple #3
0
 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
Exemple #4
0
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.')))
Exemple #5
0
 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
Exemple #6
0
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.'
              )))
Exemple #7
0
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.')
        ),
    )
Exemple #8
0
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.')))
Exemple #9
0
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
Exemple #10
0
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.'
              )))
Exemple #11
0
 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
Exemple #12
0
    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)),
            )],
        )
Exemple #13
0
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.')
        ),
    )
Exemple #14
0
 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
Exemple #15
0
 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
Exemple #16
0
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.'
              )))
Exemple #17
0
 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
Exemple #18
0
 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
Exemple #19
0
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)
Exemple #20
0
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,
    )
Exemple #21
0
 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))
Exemple #22
0
    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)),
        )
Exemple #23
0
 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)),
         },
     )
Exemple #24
0
 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.')))
Exemple #25
0
 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
Exemple #26
0
 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
Exemple #27
0
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.'))
Exemple #28
0
    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')),
        )
Exemple #29
0
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)
Exemple #30
0
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
Exemple #31
0
    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'),
        )
Exemple #32
0
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
Exemple #33
0
 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.')))
Exemple #34
0
    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)
Exemple #35
0
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
Exemple #36
0
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.'))
Exemple #37
0
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.'
              )))
Exemple #38
0
 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.'
               )),
     )
Exemple #39
0
    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)
Exemple #40
0
    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.'
                  )),
        )
Exemple #41
0
    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])
Exemple #42
0
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)
Exemple #43
0
def asset_key(assets):
    return make_name('-'.join(assets).replace('==', '-eq-').replace(
        '>=', '-gte-').replace('<=',
                               '-lte-').replace('>',
                                                '-gt-').replace('<', '-lt-'),
                     maxlength=250)
Exemple #44
0
 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)
Exemple #46
0
def asset_key(assets):
    return make_name('-'.join(assets).replace(
        '==', '-eq-').replace('>=', '-gte-').replace('<=', '-lte-').replace('>', '-gt-').replace('<', '-lt-'),
        maxlength=250)
Exemple #47
0
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))
Exemple #48
0
 def __call__(self, form, field):
     if make_name(field.data) != field.data:
         raise StopValidation(self.message)
Exemple #49
0
 def autocomplete(cls, prefix):
     search = make_name(prefix) + '%'
     return cls.query.filter(cls.name.like(search), cls.public == True).all()  # NOQA
Exemple #50
0
 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)
Exemple #52
0
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
            ))
Exemple #53
0
 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
Exemple #54
0
 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()
Exemple #55
0
def valid_name(form, field):
    field.data = make_name(field.data)