Пример #1
0
def user_create(grant_admin):
    """Creates new user"""
    update_session_options(db)
    user_type = 'user' if not grant_admin else 'admin'
    while True:
        email = prompt_email()
        if email is None:
            return
        email = email.lower()
        if not User.find(User.all_emails.contains(email), ~User.is_deleted, ~User.is_pending).count():
            break
        error('Email already exists')
    first_name = prompt("First name")
    last_name = prompt("Last name")
    affiliation = prompt("Affiliation", '')
    print()
    while True:
        username = prompt("Enter username").lower()
        if not Identity.find(provider='indico', identifier=username).count():
            break
        error('Username already exists')
    password = prompt_pass()
    if password is None:
        return

    identity = Identity(provider='indico', identifier=username, password=password)
    user = create_user(email, {'first_name': to_unicode(first_name), 'last_name': to_unicode(last_name),
                               'affiliation': to_unicode(affiliation)}, identity)
    user.is_admin = grant_admin
    print_user_info(user)

    if prompt_bool(cformat("%{yellow}Create the new {}?").format(user_type), default=True):
        db.session.add(user)
        db.session.commit()
        success("New {} created successfully with ID: {}".format(user_type, user.id))
Пример #2
0
    def sendAndLog(cls, notification, conference, module=None, user=None, skipQueue=False):
        if isinstance(notification, dict):
            # Wrap a raw dictionary in a notification class
            from MaKaC.webinterface.mail import GenericNotification

            notification = GenericNotification(notification)
        cls.send(notification, skipQueue=skipQueue)
        log_data = {
            u"content_type": to_unicode(notification.getContentType()),
            u"from": to_unicode(notification.getFromAddr()),
            u"to": map(to_unicode, notification.getToList()),
            u"cc": map(to_unicode, notification.getCCList()),
            u"bcc": map(to_unicode, notification.getBCCList()),
            u"subject": to_unicode(notification.getSubject()).strip(),
            u"body": to_unicode(notification.getBody()).strip(),
        }
        summary = u"Sent email: {}".format(log_data[u"subject"])
        conference.log(
            EventLogRealm.emails,
            EventLogKind.other,
            to_unicode(module or u"Unknown"),
            summary,
            user,
            type_=u"email",
            data=log_data,
        )
Пример #3
0
def create(grant_admin):
    """Creates a new user"""
    user_type = 'user' if not grant_admin else 'admin'
    while True:
        email = prompt_email()
        if email is None:
            return
        email = email.lower()
        if not User.query.filter(User.all_emails == email, ~User.is_deleted, ~User.is_pending).has_rows():
            break
        print(cformat('%{red}Email already exists'))
    first_name = click.prompt("First name").strip()
    last_name = click.prompt("Last name").strip()
    affiliation = click.prompt("Affiliation", '').strip()
    print()
    while True:
        username = click.prompt("Enter username").lower().strip()
        if not Identity.find(provider='indico', identifier=username).count():
            break
        print(cformat('%{red}Username already exists'))
    password = prompt_pass()
    if password is None:
        return

    identity = Identity(provider='indico', identifier=username, password=password)
    user = create_user(email, {'first_name': to_unicode(first_name), 'last_name': to_unicode(last_name),
                               'affiliation': to_unicode(affiliation)}, identity)
    user.is_admin = grant_admin
    _print_user_info(user)

    if click.confirm(cformat("%{yellow}Create the new {}?").format(user_type), default=True):
        db.session.add(user)
        db.session.commit()
        print(cformat("%{green}New {} created successfully with ID: %{green!}{}").format(user_type, user.id))
Пример #4
0
def user_create(grant_admin):
    """Creates new user"""
    user = User()
    user_type = 'user' if not grant_admin else 'admin'

    print()
    name = prompt("First name")
    surname = prompt("Last name")
    affiliation = prompt("Affiliation")
    print()
    username = prompt("Enter username")
    email = prompt_email()
    if email is None:
        return
    password = prompt_pass()
    if password is None:
        return

    user.first_name = to_unicode(name)
    user.last_name = to_unicode(surname)
    user.affiliation = to_unicode(affiliation)
    user.email = email
    user.is_admin = grant_admin
    print_user_info(user)

    if prompt_bool(cformat("%{yellow}Create the new {}?").format(user_type), default=True):
        # TODO: adapt to new authentication system, create local identity with username/password
        # user.identities.append(UserIdentity(..., identifier=username, password=password))
        db.session.add(user)
        transaction.commit()
        success("New {} created successfully with ID: {}".format(user_type, user.id))
Пример #5
0
def serialize_event(cal, fossil, now, id_prefix="indico-event"):
    event = ical.Event()
    event.add('uid', '{}-{}@{}'.format(id_prefix, fossil['id'], url_parse(config.BASE_URL).host))
    event.add('dtstamp', now)
    event.add('dtstart', _deserialize_date(fossil['startDate']))
    event.add('dtend', _deserialize_date(fossil['endDate']))
    event.add('url', fossil['url'])
    event.add('summary', to_unicode(fossil['title']))
    loc = fossil['location'] or ''
    if loc:
        loc = to_unicode(loc)
    if fossil['roomFullname']:
        loc += ' ' + to_unicode(fossil['roomFullname'])
    event.add('location', loc)
    description = ''
    if fossil.get('speakers'):
        speakers = ('{} ({})'.format(speaker['fullName'].encode('utf-8'),
                                     speaker['affiliation'].encode('utf-8')) for speaker in fossil['speakers'])
        description += 'Speakers: {}\n'.format(', '.join(speakers))

    if fossil['description']:
        desc_text = fossil['description'].strip()
        if not desc_text:
            desc_text = '<p/>'
        try:
            description += '{}\n\n{}'.format(to_unicode(html.fromstring(to_unicode(desc_text))
                                                        .text_content()).encode('utf-8'),
                                             fossil['url'].encode('utf-8'))
        except ParserError:
            # this happens e.g. if desc_text contains only a html comment
            description += fossil['url'].encode('utf-8')
    else:
        description += fossil['url']
    event.add('description', description)
    cal.add_component(event)
Пример #6
0
    def display(self, **params):
        from indico.modules.admin import RHAdminBase
        from indico.modules.core.settings import core_settings, social_settings

        title_parts = [self.title]
        if self.MANAGEMENT:
            title_parts.insert(0, _('Management'))
        elif isinstance(self._rh, RHAdminBase):
            title_parts.insert(0, _('Administration'))

        injected_bundles = values_from_signal(signals.plugin.inject_bundle.send(self.__class__), as_list=True,
                                              multi_value_types=list)
        custom_js = list(current_app.manifest['__custom.js'])
        custom_css = list(current_app.manifest['__custom.css'])
        css_files = map(self._fix_path, self.get_extra_css_files() + custom_css)
        js_files = map(self._fix_path, custom_js)

        body = to_unicode(self._display(params))
        bundles = itertools.chain((current_app.manifest[x] for x in self._resolve_bundles()
                                   if x in current_app.manifest._entries),
                                  self.additional_bundles['screen'], injected_bundles)
        print_bundles = itertools.chain((current_app.manifest[x] for x in self.print_bundles),
                                        self.additional_bundles['print'])

        return render_template('indico_base.html',
                               css_files=css_files, js_files=js_files,
                               bundles=bundles, print_bundles=print_bundles,
                               site_name=core_settings.get('site_title'),
                               social=social_settings.get_all(),
                               page_title=' - '.join(unicode(x) for x in title_parts if x),
                               head_content=to_unicode(self._getHeadContent()),
                               body=body)
Пример #7
0
    def _process_POST(self):
        if User.has_rows():
            return redirect(url_for('misc.index'))
        setup_form = BootstrapForm(request.form)
        if not setup_form.validate():
            flash(_("Some fields are invalid. Please, correct them and submit the form again."), 'error')
            return redirect(url_for('bootstrap.index'))

        # Creating new user
        user = User()
        user.first_name = to_unicode(setup_form.first_name.data)
        user.last_name = to_unicode(setup_form.last_name.data)
        user.affiliation = to_unicode(setup_form.affiliation.data)
        user.email = to_unicode(setup_form.email.data)
        user.is_admin = True

        identity = Identity(provider='indico', identifier=setup_form.username.data, password=setup_form.password.data)
        user.identities.add(identity)

        db.session.add(user)
        db.session.flush()

        user.settings.set('timezone', Config.getInstance().getDefaultTimezone())
        user.settings.set('lang', to_unicode(setup_form.language.data))

        login_user(user, identity)
        full_name = user.full_name  # needed after the session closes

        transaction.commit()

        # Configuring server's settings
        minfo = HelperMaKaCInfo.getMaKaCInfoInstance()
        minfo.setOrganisation(setup_form.affiliation.data)
        minfo.setLang(setup_form.language.data)

        message = get_template_module('bootstrap/flash_messages.html').bootstrap_success(name=full_name)
        flash(Markup(message), 'success')

        # Activate instance tracking
        if setup_form.enable_tracking.data:
            contact_name = setup_form.contact_name.data
            contact_email = setup_form.contact_email.data

            try:
                register_instance(contact_name, contact_email)
            except (HTTPError, ValueError) as err:
                message = get_template_module('bootstrap/flash_messages.html').community_error(err=err)
                category = 'error'
            except Timeout:
                message = get_template_module('bootstrap/flash_messages.html').community_timeout()
                category = 'error'
            except RequestException as exc:
                message = get_template_module('bootstrap/flash_messages.html').community_exception(exc=exc)
                category = 'error'
            else:
                message = get_template_module('bootstrap/flash_messages.html').community_success()
                category = 'success'
            flash(Markup(message), category)

        return redirect(url_for('misc.index'))
Пример #8
0
    def display(self, **params):
        from indico.modules.admin import RHAdminBase
        from indico.modules.core.settings import core_settings, social_settings

        title_parts = [to_unicode(self._getTitle())]
        if self.MANAGEMENT:
            title_parts.append(_('Management area'))
        elif isinstance(self._rh, RHAdminBase):
            title_parts.append(_('Administration area'))

        plugin_css = values_from_signal(signals.plugin.inject_css.send(self.__class__), as_list=True,
                                        multi_value_types=list)
        plugin_js = values_from_signal(signals.plugin.inject_js.send(self.__class__), as_list=True,
                                       multi_value_types=list)
        custom_js = self._asset_env['custom_js'].urls() if 'custom_js' in self._asset_env else []
        custom_css = self._asset_env['custom_sass'].urls() if 'custom_sass' in self._asset_env else []
        css_files = map(self._fix_path, self.getCSSFiles() + plugin_css + self.get_extra_css_files() + custom_css)
        print_css_files = map(self._fix_path, self.getPrintCSSFiles())
        js_files = map(self._fix_path, self.getJSFiles() + plugin_js + custom_js)

        body = to_unicode(self._display(params))

        return render_template('indico_base.html',
                               css_files=css_files, print_css_files=print_css_files, js_files=js_files,
                               site_name=core_settings.get('site_title'),
                               social=social_settings.get_all(),
                               page_title=' - '.join(title_parts),
                               head_content=to_unicode(self._getHeadContent()),
                               body=body)
Пример #9
0
 def _get_email_subject(self, **mail_params):
     return u'{prefix}[{room}] {subject} {date} {suffix}'.format(
         prefix=to_unicode(mail_params.get('subject_prefix', '')),
         room=self.reservation.room.full_name,
         subject=to_unicode(mail_params.get('subject', '')),
         date=to_unicode(self.start_dt),
         suffix=to_unicode(mail_params.get('subject_suffix', ''))
     ).strip()
Пример #10
0
 def _format_contrib(contrib):
     if contrib.getSession() is None:
         return to_unicode(contrib.getTitle())
     else:
         return _('{contrib} (in session "{session}")').format(
             session=to_unicode(contrib.getSession().getTitle()),
             contrib=to_unicode(contrib.getTitle())
         )
Пример #11
0
def make_email(to_list=None, cc_list=None, bcc_list=None, from_address=None, reply_address=None, attachments=None,
               subject=None, body=None, template=None, html=False):
    """Creates an email.

    The preferred way to specify the email content is using the
    `template` argument. To do so, use :func:`.get_template_module` on
    a template inheriting from ``emails/base.txt`` for text emails or
    ``emails/base.html`` for HTML emails.

    :param to_list: The recipient email or a collection of emails
    :param cc_list: The CC email or a collection of emails
    :param bcc_list: The BCC email or a collection of emails
    :param from_address: The sender address. Defaults to noreply.
    :param reply_address: The reply-to address or a collection of addresses.
                          Defaults to empty.
    :param attachments: A list of attachments. Each attachment can be
                        a `MIMEBase` subclass, a 3-tuple of the form
                        ``(filename, content, mimetype)``, or a 2-tuple
                        ``(filename, content)`` in which case the mime
                        type will be guessed from the file name.
    :param subject: The subject of the email.
    :param body: The body of the email:
    :param template: A template module containing ``get_subject`` and
                     ``get_body`` macros.
    :param html: ``True`` if the email body is HTML
    """
    if template is not None and (subject is not None or body is not None):
        raise ValueError("Only subject/body or template can be passed")

    if template:
        subject = template.get_subject()
        body = template.get_body()
    if config.DEBUG and '\n' in subject:
        raise ValueError('Email subject contains linebreaks')
    subject = re.sub(r'\s+', ' ', subject)
    if to_list is None:
        to_list = set()
    if cc_list is None:
        cc_list = set()
    if bcc_list is None:
        bcc_list = set()
    to_list = {to_list} if isinstance(to_list, basestring) else to_list
    cc_list = {cc_list} if isinstance(cc_list, basestring) else cc_list
    bcc_list = {bcc_list} if isinstance(bcc_list, basestring) else bcc_list
    reply_address = {reply_address} if isinstance(reply_address, basestring) else (reply_address or set())
    return {
        'to': set(map(to_unicode, to_list)),
        'cc': set(map(to_unicode, cc_list)),
        'bcc': set(map(to_unicode, bcc_list)),
        'from': to_unicode(from_address or config.NO_REPLY_EMAIL),
        'reply_to': set(map(to_unicode, reply_address)),
        'attachments': attachments or [],
        'subject': to_unicode(subject).strip(),
        'body': to_unicode(body).strip(),
        'html': html,
    }
Пример #12
0
def handle_exception(exc, message=None):
    Logger.get('flask').exception(to_unicode(exc.message) or 'Uncaught Exception')
    if not current_app.debug or request.is_xhr or request.is_json:
        sentry_log_exception()
        if message is None:
            message = '{}: {}'.format(type(exc).__name__, to_unicode(exc.message))
        return render_error(exc, _('Something went wrong'), message, 500)
    # Let the exception propagate to middleware /the webserver.
    # This triggers the Flask debugger in development and sentry
    # logging (if enabled) (via got_request_exception).
    raise
Пример #13
0
 def format_event_date(self, event):
     day_month = 'dd MMM'
     tzinfo = self.category.display_tzinfo
     start_dt = event.start_dt.astimezone(tzinfo)
     end_dt = event.end_dt.astimezone(tzinfo)
     if start_dt.year != end_dt.year:
         return '{} - {}'.format(to_unicode(format_date(start_dt, timezone=tzinfo)),
                                 to_unicode(format_date(end_dt, timezone=tzinfo)))
     elif (start_dt.month != end_dt.month) or (start_dt.day != end_dt.day):
         return '{} - {}'.format(to_unicode(format_date(start_dt, day_month, timezone=tzinfo)),
                                 to_unicode(format_date(end_dt, day_month, timezone=tzinfo)))
     else:
         return to_unicode(format_date(start_dt, day_month, timezone=tzinfo))
Пример #14
0
 def __init__(self, rh, event_, **kwargs):
     assert event_ == kwargs.setdefault('event', event_)
     self.event = event_
     WPDecorated.__init__(self, rh, **kwargs)
     start_dt_local = event_.start_dt_display.astimezone(event_.display_tzinfo)
     end_dt_local = event_.end_dt_display.astimezone(event_.display_tzinfo)
     dates = ' ({})'.format(to_unicode(format_date(start_dt_local, format='long')))
     if start_dt_local.date() != end_dt_local.date():
         if start_dt_local.year == end_dt_local.year and start_dt_local.month == end_dt_local.month:
             dates = ' ({}-{})'.format(start_dt_local.day, to_unicode(format_date(end_dt_local, format='long')))
         else:
             dates = ' ({} - {})'.format(to_unicode(format_date(start_dt_local, format='long')),
                                         to_unicode(format_date(end_dt_local, format='long')))
     self.title = '{} {}'.format(strip_tags(self.event.title), dates)
Пример #15
0
def generate_spreadsheet_from_registrations(registrations, regform_items, special_items):
    """Generates a spreadsheet data from a given registration list.

    :param registrations: The list of registrations to include in the file
    :param regform_items: The registration form items to be used as columns
    :param special_items: Registration form information as extra columns
    """
    field_names = ['ID', 'Name']
    special_item_mapping = OrderedDict([
        ('reg_date', ('Registration date', lambda x: to_unicode(format_datetime(x.submitted_dt)))),
        ('state', ('Registration state', lambda x: x.state.title)),
        ('price', ('Price', lambda x: x.render_price())),
        ('checked_in', ('Checked in', lambda x: x.checked_in)),
        ('checked_in_date', ('Check-in date', lambda x: (to_unicode(format_datetime(x.checked_in_dt)) if x.checked_in
                                                         else '')))
    ])
    for item in regform_items:
        field_names.append('{}_{}'.format(item.title, item.id))
        if item.input_type == 'accommodation':
            field_names.append('{}_{}_{}'.format(item.title, 'Arrival', item.id))
            field_names.append('{}_{}_{}'.format(item.title, 'Departure', item.id))
    field_names.extend(title for name, (title, fn) in special_item_mapping.iteritems() if name in special_items)
    rows = []
    for registration in registrations:
        data = registration.data_by_field
        registration_dict = {
            'ID': registration.friendly_id,
            'Name': "{} {}".format(registration.first_name, registration.last_name)
        }
        for item in regform_items:
            key = '{}_{}'.format(item.title, item.id)
            if item.input_type == 'accommodation':
                registration_dict[key] = _prepare_data(data[item.id].friendly_data.get('choice')
                                                       if item.id in data else '')
                key = '{}_{}_{}'.format(item.title, 'Arrival', item.id)
                arrival_date = data[item.id].friendly_data.get('arrival_date') if item.id in data else None
                registration_dict[key] = _prepare_data(format_date(arrival_date) if arrival_date else '')
                key = '{}_{}_{}'.format(item.title, 'Departure', item.id)
                departure_date = data[item.id].friendly_data.get('departure_date') if item.id in data else None
                registration_dict[key] = _prepare_data(format_date(departure_date) if departure_date else '')
            else:
                registration_dict[key] = _prepare_data(data[item.id].friendly_data if item.id in data else '')
        for name, (title, fn) in special_item_mapping.iteritems():
            if name not in special_items:
                continue
            value = fn(registration)
            registration_dict[title] = value
        rows.append(registration_dict)
    return field_names, rows
Пример #16
0
 def _getAnswer(self):
     event_persons = []
     users = searchUsers(self._surName, self._name, self._organisation, self._email,
                         self._exactMatch, self._searchExt)
     if self._event:
         fields = {EventPerson.first_name: self._name,
                   EventPerson.last_name: self._surName,
                   EventPerson.email: self._email,
                   EventPerson.affiliation: self._organisation}
         criteria = [unaccent_match(col, val, exact=self._exactMatch) for col, val in fields.iteritems()]
         event_persons = self._event.persons.filter(*criteria).all()
     fossilized_users = fossilize(sorted(users, key=lambda av: (av.getStraightFullName(), av.getEmail())))
     fossilized_event_persons = map(serialize_event_person, event_persons)
     unique_users = {to_unicode(user['email']): user for user in chain(fossilized_users, fossilized_event_persons)}
     return sorted(unique_users.values(), key=lambda x: (to_unicode(x['name']).lower(), to_unicode(x['email'])))
Пример #17
0
    def get_allowed_sender_emails(self, include_current_user=True, include_creator=True, include_managers=True,
                                  include_support=True, include_chairs=True, extra=None):
        """
        Return the emails of people who can be used as senders (or
        rather Reply-to contacts) in emails sent from within an event.

        :param include_current_user: Whether to include the email of
                                     the currently logged-in user
        :param include_creator: Whether to include the email of the
                                event creator
        :param include_managers: Whether to include the email of all
                                 event managers
        :param include_support: Whether to include the "event support"
                                email
        :param include_chairs: Whether to include the emails of event
                               chairpersons (or lecture speakers)
        :param extra: An email address that is always included, even
                      if it is not in any of the included lists.
        :return: An OrderedDict mapping emails to pretty names
        """
        emails = {}
        # Support
        if include_support:
            support = self.as_legacy.getSupportInfo()
            emails[support.getEmail()] = support.getCaption() or support.getEmail()
        # Current user
        if include_current_user and has_request_context() and session.user:
            emails[session.user.email] = session.user.full_name
        # Creator
        if include_creator:
            emails[self.creator.email] = self.creator.full_name
        # Managers
        if include_managers:
            emails.update((p.principal.email, p.principal.full_name)
                          for p in self.acl_entries
                          if p.type == PrincipalType.user and p.full_access)
        # Chairs
        if include_chairs:
            emails.update((pl.email, pl.full_name) for pl in self.person_links if pl.email)
        # Extra email (e.g. the current value in an object from the DB)
        if extra:
            emails.setdefault(extra, extra)
        # Sanitize and format emails
        emails = {to_unicode(email.strip().lower()): '{} <{}>'.format(to_unicode(name), to_unicode(email))
                  for email, name in emails.iteritems()
                  if email and email.strip()}
        own_email = session.user.email if has_request_context() and session.user else None
        return OrderedDict(sorted(emails.items(), key=lambda x: (x[0] != own_email, x[1].lower())))
Пример #18
0
def _build_match(column, value, exact):
    value = to_unicode(value).replace('%', r'\%').replace('_', r'\_').lower()
    if not exact:
        value = '%{}%'.format(value)
    # we always use LIKE, even for an exact match. when using the pg_trgm indexes this is
    # actually faster than `=`
    return db.func.indico_unaccent(db.func.lower(column)).ilike(db.func.indico_unaccent(value))
Пример #19
0
 def render(cls, regform, registration):
     event = registration.registration_form.event
     return Markup(
         '<a href="{url}" title="{title}">{url}</a>'.format(
             url=event.getURL(), title=escape(to_unicode(event.title))
         )
     )
Пример #20
0
def verbose_iterator(iterable, total, get_id, get_title):
    """Iterates large iterables verbosely

    :param iterable: An iterable
    :param total: The number of items in `iterable`
    :param get_id: callable to retrieve the ID of an item
    :param get_title: callable to retrieve the title of an item
    """
    term_width = terminal_size()[0]
    start_time = time.time()
    fmt = cformat(
        '[%{cyan!}{:6}%{reset}/%{cyan}{}%{reset}  %{yellow!}{:.3f}%{reset}%  %{green!}{}%{reset}]  {:>8}  %{grey!}{}'
    )

    for i, item in enumerate(iterable, 1):
        if i % 10 == 0 or i == total:
            remaining_seconds = int((time.time() - start_time) / i * (total - i))
            remaining = '{:02}:{:02}'.format(remaining_seconds // 60, remaining_seconds % 60)
            title = to_unicode(get_title(item).replace('\n', ' '))
            text = fmt.format(i, total, (i / total * 100.0), remaining, get_id(item), title)
            print('\r', ' ' * term_width, end='', sep='')
            # terminal width + ansi control code length - trailing reset code (4)
            print('\r', text[:term_width + len(text.value_colors) - len(text.value_no_colors) - 4], cformat('%{reset}'),
                  end='', sep='')
            sys.stdout.flush()

        yield item

    print()
Пример #21
0
        def _iterate_objs(query_string):
            query = (Event.query
                     .filter(Event.title_matches(to_unicode(query_string)),
                             ~Event.is_deleted)
                     .options(undefer('effective_protection_mode')))
            sort_dir = db.desc if self._descending else db.asc
            if self._orderBy == 'start':
                query = query.order_by(sort_dir(Event.start_dt))
            elif self._orderBy == 'end':
                query = query.order_by(sort_dir(Event.end_dt))
            elif self._orderBy == 'id':
                query = query.order_by(sort_dir(Event.id))
            elif self._orderBy == 'title':
                query = query.order_by(sort_dir(db.func.lower(Event.title)))

            counter = 0
            # Query the DB in chunks of 1000 records per query until the limit is satisfied
            for event in query.yield_per(1000):
                if event.can_access(self._user):
                    counter += 1
                    # Start yielding only when the counter reaches the given offset
                    if (self._offset is None) or (counter > self._offset):
                        yield event
                        # Stop querying the DB when the limit is satisfied
                        if (self._limit is not None) and (counter == self._offset + self._limit):
                            break
Пример #22
0
    def all_recipients(self):
        """Returns all recipients of the notifications.

        This includes both explicit recipients and, if enabled,
        participants of the event.
        """
        recipients = set(self.recipients)
        if self.send_to_participants:
            event = self.event
            if event.getType() == 'conference':
                recipients.update(to_unicode(r.getEmail().strip().lower()) for r in event.getRegistrantsList())
            else:
                recipients.update(to_unicode(p.getEmail().strip().lower())
                                  for p in event.getParticipation().getParticipantList())
        recipients.discard('')  # just in case there was an empty email address somewhere
        return recipients
Пример #23
0
def serialize_category_atom(category, url, user, event_filter):
    """Export the events in a category to Atom

    :param category: The category to export
    :param url: The URL of the feed
    :param user: The user who needs to be able to access the events
    :param event_filter: A SQLalchemy criterion to restrict which
                         events will be returned.  Usually something
                         involving the start/end date of the event.
    """
    query = (Event.query
             .filter(Event.category_chain.contains([int(category.getId())]),
                     ~Event.is_deleted,
                     event_filter)
             .options(load_only('id', 'start_dt', 'title', 'description', 'protection_mode'),
                      subqueryload('acl_entries'))
             .order_by(Event.start_dt))
    events = [e for e in query if e.can_access(user)]

    feed = AtomFeed(feed_url=url, title='Indico Feed [{}]'.format(to_unicode(category.getTitle())))
    for event in events:
        feed.add(title=event.title,
                 summary=unicode(event.description),  # get rid of RichMarkup
                 url=url_for('event.conferenceDisplay', confId=event.id, _external=True),
                 updated=event.start_dt)
    return BytesIO(feed.to_string().encode('utf-8'))
Пример #24
0
    def removeParticipant(self, participant, responsibleUser=None):
        if participant is None:
            return False
        # If 'participant' is an object from Participant
        if isinstance(participant, Participant):
            # remove all entries with participant
            for key, value in self._participantList.items():
                if value == participant:
                    del self._participantList[key]
        # If 'participant' is a key
        else:
            key = participant
            if key not in self._participantList:
                return False
            participant = self._participantList[key]
            del self._participantList[key]

        self.getConference().log(EventLogRealm.management, EventLogKind.negative, u'Participants',
                                 u'Participant removed: {}'.format(to_unicode(participant.getName())),
                                 session.user, data=participant.getParticipantData())
        avatar = participant.getAvatar()
        if avatar:
            avatar.unlinkTo(self._conference,"participant")
        if participant._status in {'added', 'accepted'}:
            signals.event.participant_changed.send(self._conference, user=avatar, participant=participant,
                                                   old_status=participant._status, action='removed')
        self.notifyModification()
        return True
Пример #25
0
def get_time_changes_notifications(changes, tzinfo, entry=None):
    notifications = []
    for obj, change in changes.iteritems():
        if entry:
            if entry.object == obj:
                continue
            if not isinstance(obj, Event) and obj.timetable_entry in entry.children:
                continue
        msg = None
        if isinstance(obj, Event):
            if 'start_dt' in change:
                new_time = change['start_dt'][1]
                msg = _("Event start time changed to {}")
            elif 'end_dt' in change:
                new_time = change['end_dt'][1]
                msg = _("Event end time changed to {}")
            else:
                raise ValueError("Invalid change in event.")
        elif isinstance(obj, SessionBlock):
            if 'start_dt' in change:
                new_time = change['start_dt'][1]
                msg = _("Session block start time changed to {}")
            elif 'end_dt' in change:
                new_time = change['end_dt'][1]
                msg = _("Session block end time changed to {}")
            else:
                raise ValueError("Invalid change in session block.")
        if msg:
            notifications.append(msg.format(to_unicode(format_time(new_time, timezone=tzinfo))))
    return notifications
Пример #26
0
    def _process(self):
        if self._getUser() is not None and self._getUser().isRegisteredInConf(self._conf):
            if (
                not self._conf.getRegistrationForm().inRegistrationPeriod()
                and not self._conf.getRegistrationForm().inModificationPeriod()
            ):
                flash(_("Your modification could not be recorded since the modification period is over."), "error")
                return redirect(url_for("event.confRegistrationFormDisplay", self._conf))
            else:
                rp = self._getUser().getRegistrantById(self._conf.getId())

                # Check if the email matches an existing user
                params = self._getRequestParams()
                email = self._regForm.getPersonalData().getValueFromParams(params, "email") or ""
                user = get_user_by_email(email)
                if user:
                    if not session.user:
                        flash(
                            _(
                                "The provided email ({email}) is linked to an Indico account. Please sign in with it "
                                "first."
                            ).format(email=email),
                            "error",
                        )
                        return redirect(url_for("event.confRegistrationFormDisplay-modify", self._conf))
                    elif session.user != user:
                        flash(
                            _(
                                "The provided email ({email}) is linked to another Indico account. Please sign in with "
                                "it first."
                            ).format(email=email),
                            "error",
                        )
                        return redirect(url_for("event.confRegistrationFormDisplay-modify", self._conf))

                # check if the email is being changed by another one that already exists
                if email != rp.getEmail() and self._conf.hasRegistrantByEmail(email):
                    raise FormValuesError(
                        _('There is already a user with the email "{email}". ' "Please choose another one.").format(
                            email or "--no email--"
                        )
                    )
                rp.setValues(self._getRequestParams(), self._getUser())
                log_msg = u"User modified his registration data: {}"
                self._conf.log(
                    EventLogRealm.participants,
                    EventLogKind.positive,
                    u"Registration",
                    log_msg.format(to_unicode(rp.getFullName(title=False, firstNameFirst=True))),
                    session.user,
                    data={u"Indico user": u"{} ({})".format(user.full_name, user.id) if user else u"None"},
                )
                notify_registration_modification(self._conf, rp)
                flash(_(u"Your registration has been modified successfully."), "success")
                if rp.doPay():
                    self._redirect(urlHandlers.UHConfRegistrationFormCreationDone.getURL(rp))
                else:
                    self._redirect(urlHandlers.UHConfRegistrationForm.getURL(self._conf))
        else:
            self._redirect(urlHandlers.UHConfRegistrationForm.getURL(self._conf))
Пример #27
0
def _get_reg_details(reg_form, registrant):
    reg_details = {'misc_details': OrderedDict(), 'personal_data': OrderedDict()}
    for section in reg_form.getSortedForms():
        if section.getId() == 'reasonParticipation':
            reg_details['reason'] = registrant.getReasonParticipation()
        elif section.getId() == 'sessions':
            reg_details['sessions_type'] = 'priorities' if section.getType() == '2priorities' else None
            reg_details['sessions'] = [to_unicode(session.getTitle()) for session in registrant.getSessionList()]
        elif section.getId() == 'accommodation' and section.isEnabled():
            accommodation = registrant.getAccommodation()
            if accommodation.getAccommodationType():
                reg_details['accommodation_type'] = accommodation.getAccommodationType().getCaption()
                reg_details['accommodation_arrival'] = accommodation.getArrivalDate().strftime('%d %B %Y')
                reg_details['accommodation_departure'] = accommodation.getDepartureDate().strftime('%d %B %Y')
        elif section.getId() == 'socialEvents' and section.isEnabled():
            reg_details['social'] = {}
            for social_event in registrant.getSocialEvents():
                reg_details['social'][social_event.getCaption()] = social_event.getNoPlaces()
        elif section.getId() == 'furtherInformation':
            pass
        elif section.isEnabled():
            misc = registrant.getMiscellaneousGroupById(section.getId())
            if not misc:
                continue
            title = to_unicode(misc.getTitle())
            fields = OrderedDict()
            for field in section.getSortedFields():
                response_item = misc.getResponseItemById(field.getId())
                if not response_item:
                    continue
                input_field = response_item.getGeneralField().getInput()
                form_field = {'value': response_item.getValue(),
                              'caption': to_unicode(response_item.getCaption())}
                if response_item.isBillable():
                    form_field['price'] = response_item.getPrice()
                    form_field['currency'] = response_item.getCurrency()
                if form_field['value']:
                    try:
                        form_field['value'] = to_unicode(input_field.getValueDisplay(form_field['value']))
                    except Exception:
                        form_field['value'] = to_unicode(form_field['value']).strip()
                fields[field.getId()] = form_field
            if isinstance(section, PersonalDataForm):
                reg_details['personal_data'][title] = fields
            else:
                reg_details['misc_details'][title] = fields
    return reg_details
Пример #28
0
    def _process(self):
        canManageRegistration = self._conf.canManageRegistration(self._getUser())
        if not canManageRegistration and not self._regForm.isActivated():
            p = registrationForm.WPRegFormInactive(self, self._conf)
            return p.display()
        params = self._getRequestParams()
        email = self._regForm.getPersonalData().getValueFromParams(params, 'email')
        if email is None:
            raise FormValuesError(_("An email address has to be set in order to make the registration in the event."))
        elif not validMail(email, False):
            raise FormValuesError(_("The given email address is not valid."))

        # Check if the email matches an existing user
        user = get_user_by_email(email)
        avatar = user.as_avatar if user else None

        # Check if the user can register
        if not canManageRegistration:  # normal user registering. Managers can.
            if self._conf.getRegistrationForm().isFull():
                self._redirect(urlHandlers.UHConfRegistrationFormDisplay.getURL(self._conf))
                return
            elif not self._conf.getRegistrationForm().inRegistrationPeriod():
                flash(_("Your registration couldn't be recorded."), 'error')
                return redirect(url_for('event.confRegistrationFormDisplay', self._conf))
        if user is None:
            if self._conf.hasRegistrantByEmail(email):
                raise FormValuesError("There is already a user with the email \"%s\". Please choose another one" % email)
        else:
            if avatar.isRegisteredInConf(self._conf) or self._conf.hasRegistrantByEmail(email):
                if canManageRegistration:
                    raise FormValuesError("There is already a user with the email \"%s\". Please choose another one" % email)
                else:
                    raise FormValuesError("You have already registered with the email address \"%s\". If you need to modify your registration, please contact the managers of the conference." % email)

        rp = registration.Registrant()
        self._conf.addRegistrant(rp, avatar)
        rp.setValues(self._getRequestParams(), avatar)

        if avatar is not None:
            rp.setAvatar(avatar)

        notify_registration_confirmation(self._conf, rp)
        self._conf.log(EventLogRealm.management if self.is_manager else EventLogRealm.participants,
                       EventLogKind.positive, u'Registration',
                       u'User registered: {}'.format(to_unicode(rp.getFullName(title=False, firstNameFirst=True))),
                       session.user,
                       data={u'Indico user': u'{} ({})'.format(user.full_name, user.id) if user else u'None'})

        if self.is_manager:
            self._redirect(RHRegistrantListModif._uh.getURL(self._conf))
        else:
            params = {}
            if not rp.doPay() or not payment_event_settings.get(self._conf, 'enabled'):
                flash(_(u"Your registration has been recorded successfully."), 'success')
            if not session.user or session.user != user:
                params.update(rp.getLocator(), **{'authkey': rp.getRandomId()})
            else:
                params.update(self._conf.getLocator())
            return redirect(url_for('event.confRegistrationFormDisplay', **params))
Пример #29
0
 def _set_email_choices(self):
     # User
     emails = {session.user.email: session.user.full_name}
     # Creator
     emails[self.event.getCreator().getEmail()] = self.event.getCreator().getStraightFullName(upper=False)
     # Support
     support = self.event.getSupportInfo()
     emails[support.getEmail()] = support.getCaption() or support.getEmail()
     # Chairs
     emails.update((x.getEmail(), x.getDirectFullName()) for x in self.event.getChairList())
     # Current email to avoid destructive modifications
     emails.setdefault(self.reply_to_address.object_data, self.reply_to_address.object_data)
     # Sanitize and format emails
     emails = {to_unicode(email.strip().lower()): '{} <{}>'.format(to_unicode(name), to_unicode(email))
               for email, name in emails.iteritems()
               if email and email.strip()}
     self.reply_to_address.choices = sorted(emails.items(), key=lambda x: (x[0] != session.user.email, x[1].lower()))
Пример #30
0
 def setStatusDeclined(self, responsibleUser=None):
     if self._status != "pending" :
         return False
     self._status = "declined"
     self.getConference().log(EventLogRealm.management, EventLogKind.negative, u'Participants',
                              u"Participation request declined: {}".format(to_unicode(self.getName())),
                              session.user, data=self.getParticipantData())
     return True
Пример #31
0
            if responseUtil.status == 405:
                responseUtil.headers[
                    'Allow'] = 'GET' if request.method == 'POST' else 'POST'

    if result is None and error is None:
        # TODO: usage page
        raise NotFound
    else:
        if ak and error is None:
            # Commit only if there was an API key and no error
            norm_path, norm_query = normalizeQuery(path,
                                                   query,
                                                   remove=('signature',
                                                           'timestamp'),
                                                   separate=True)
            uri = to_unicode('?'.join(filter(None, (norm_path, norm_query))))
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            transaction.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            transaction.abort()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s' % (path, query))

        serializer = Serializer.create(dformat,
                                       query_params=queryParams,
                                       pretty=pretty,
                                       typeMap=typeMap,
Пример #32
0
 def __init__(self, text, style, part="", bulletText=None, frags=None, caseSensitive=1):
     platypus.Paragraph.__init__(self, to_unicode(text), style, bulletText, frags, caseSensitive)
     self._part = part
Пример #33
0
def handle_badrequestkeyerror(exc):
    if current_app.debug:
        raise
    msg = _('Required argument missing: {}').format(to_unicode(exc.message))
    return render_error(exc, exc.name, msg, exc.code)
Пример #34
0
def handle_indico_exception(exc):
    return render_error(exc, _('Something went wrong'),
                        to_unicode(exc.message),
                        getattr(exc, 'http_status_code', 500))
Пример #35
0
 def setName(self, name, reindex=False):
     self.user.first_name = to_unicode(name)
Пример #36
0
 def setOrganisation(self, affiliation, reindex=False):
     self.user.affiliation = to_unicode(affiliation)
Пример #37
0
 def setTimezone(self, tz):
     self.user.settings.set('timezone', to_unicode(tz))
Пример #38
0
    def modify(self, data, user):
        """Modifies an existing reservation.

        :param data: A dict containing the booking data, usually from a :class:`ModifyBookingForm` instance
        :param user: The :class:`.User` who modifies the booking.
        """

        populate_fields = ('start_dt', 'end_dt', 'repeat_frequency',
                           'repeat_interval', 'booked_for_user',
                           'contact_email', 'contact_phone', 'booking_reason',
                           'used_equipment', 'needs_assistance', 'uses_vc',
                           'needs_vc_assistance')
        # fields affecting occurrences
        occurrence_fields = {
            'start_dt', 'end_dt', 'repeat_frequency', 'repeat_interval'
        }
        # fields where date and time are compared separately
        date_time_fields = {'start_dt', 'end_dt'}
        # fields for the repetition
        repetition_fields = {'repeat_frequency', 'repeat_interval'}
        # pretty names for logging
        field_names = {
            'start_dt/date': u"start date",
            'end_dt/date': u"end date",
            'start_dt/time': u"start time",
            'end_dt/time': u"end time",
            'repetition': u"booking type",
            'booked_for_user': u"'Booked for' user",
            'contact_email': u"contact email",
            'contact_phone': u"contact phone number",
            'booking_reason': u"booking reason",
            'used_equipment': u"list of equipment",
            'needs_assistance': u"option 'General Assistance'",
            'uses_vc': u"option 'Uses Videoconference'",
            'needs_vc_assistance': u"option 'Videoconference Setup Assistance'"
        }

        self.room.check_advance_days(data['end_dt'].date(), user)
        self.room.check_bookable_hours(data['start_dt'].time(),
                                       data['end_dt'].time(), user)

        changes = {}
        update_occurrences = False
        old_repetition = self.repetition

        for field in populate_fields:
            if field not in data:
                continue
            old = getattr(self, field)
            new = data[field]
            converter = unicode
            if field == 'used_equipment':
                # Dynamic relationship
                old = sorted(old.all())
                converter = lambda x: u', '.join(x.name for x in x)
            if old != new:
                # Booked for user updates the (redundant) name
                if field == 'booked_for_user':
                    old = self.booked_for_name
                    new = self.booked_for_name = data[field].full_name
                # Apply the change
                setattr(self, field, data[field])
                # If any occurrence-related field changed we need to recreate the occurrences
                if field in occurrence_fields:
                    update_occurrences = True
                # Record change for history entry
                if field in date_time_fields:
                    # The date/time fields create separate entries for the date and time parts
                    if old.date() != new.date():
                        changes[field + '/date'] = {
                            'old': old.date(),
                            'new': new.date(),
                            'converter': format_date
                        }
                    if old.time() != new.time():
                        changes[field + '/time'] = {
                            'old': old.time(),
                            'new': new.time(),
                            'converter': format_time
                        }
                elif field in repetition_fields:
                    # Repetition needs special handling since it consists of two fields but they are tied together
                    # We simply update it whenever we encounter such a change; after the last change we end up with
                    # the correct change data
                    changes['repetition'] = {
                        'old': old_repetition,
                        'new': self.repetition,
                        'converter': lambda x: RepeatMapping.get_message(*x)
                    }
                else:
                    changes[field] = {
                        'old': old,
                        'new': new,
                        'converter': converter
                    }

        if not changes:
            return False

        # Create a verbose log entry for the modification
        log = [u'Booking modified']
        for field, change in changes.iteritems():
            field_title = field_names.get(field, field)
            converter = change['converter']
            old = to_unicode(converter(change['old']))
            new = to_unicode(converter(change['new']))
            if not old:
                log.append(u"The {} was set to '{}'".format(field_title, new))
            elif not new:
                log.append(u"The {} was cleared".format(field_title))
            else:
                log.append(u"The {} was changed from '{}' to '{}'".format(
                    field_title, old, new))

        self.edit_logs.append(
            ReservationEditLog(user_name=user.full_name, info=log))

        # Recreate all occurrences if necessary
        if update_occurrences:
            cols = [
                col.name for col in ReservationOccurrence.__table__.columns if
                not col.primary_key and col.name not in {'start_dt', 'end_dt'}
            ]

            old_occurrences = {occ.date: occ for occ in self.occurrences}
            self.occurrences.delete(synchronize_session='fetch')
            self.create_occurrences(True, user)
            db.session.flush()
            # Restore rejection data etc. for recreated occurrences
            for occurrence in self.occurrences:
                old_occurrence = old_occurrences.get(occurrence.date)
                # Copy data from old occurrence UNLESS the new one is invalid (e.g. because of collisions)
                # Otherwise we'd end up with valid occurrences ignoring collisions!
                if old_occurrence and occurrence.is_valid:
                    for col in cols:
                        setattr(occurrence, col, getattr(old_occurrence, col))
            # Don't cause new notifications for the entire booking in case of daily repetition
            if self.repeat_frequency == RepeatFrequency.DAY and all(
                    occ.notification_sent
                    for occ in old_occurrences.itervalues()):
                for occurrence in self.occurrences:
                    occurrence.notification_sent = True

        # Sanity check so we don't end up with an "empty" booking
        if not any(occ.is_valid for occ in self.occurrences):
            raise NoReportError(_(u'Reservation has no valid occurrences'))

        notify_modification(self, changes)
        return True
Пример #39
0
 def _applyDecoration(self, body):
     if request.args.get('frame') == 'no' or request.args.get(
             'fr') == 'no' or request.args.get('print') == '1':
         return to_unicode(WPrintPageFrame().getHTML({'content': body}))
     else:
         return WPConferenceBase._applyDecoration(self, body)
Пример #40
0
def force_text(val):
    if is_lazy_string(val):
        val = val.value
    return to_unicode(val)
Пример #41
0
    def _process_POST(self):
        if User.query.filter_by(is_system=False).has_rows():
            return redirect(url_for_index())
        setup_form = BootstrapForm(request.form)
        if not setup_form.validate():
            flash(
                _("Some fields are invalid. Please, correct them and submit the form again."
                  ), 'error')
            return redirect(url_for('bootstrap.index'))

        # Creating new user
        user = User()
        user.first_name = to_unicode(setup_form.first_name.data)
        user.last_name = to_unicode(setup_form.last_name.data)
        user.affiliation = to_unicode(setup_form.affiliation.data)
        user.email = to_unicode(setup_form.email.data)
        user.is_admin = True

        identity = Identity(provider='indico',
                            identifier=setup_form.username.data,
                            password=setup_form.password.data)
        user.identities.add(identity)

        db.session.add(user)
        db.session.flush()

        user.settings.set('timezone', config.DEFAULT_TIMEZONE)
        user.settings.set('lang', session.lang or config.DEFAULT_LOCALE)

        login_user(user, identity)
        full_name = user.full_name  # needed after the session closes

        db.session.commit()

        # Configuring server's settings
        core_settings.set('site_organization', setup_form.affiliation.data)

        message = get_template_module(
            'bootstrap/flash_messages.html').bootstrap_success(name=full_name)
        flash(Markup(message), 'success')

        # Activate instance tracking
        if setup_form.enable_tracking.data:
            contact_name = setup_form.contact_name.data
            contact_email = setup_form.contact_email.data

            try:
                register_instance(contact_name, contact_email)
            except (HTTPError, ValueError) as err:
                message = get_template_module(
                    'bootstrap/flash_messages.html').community_error(err=err)
                category = 'error'
            except Timeout:
                message = get_template_module(
                    'bootstrap/flash_messages.html').community_timeout()
                category = 'error'
            except RequestException as exc:
                message = get_template_module('bootstrap/flash_messages.html'
                                              ).community_exception(exc=exc)
                category = 'error'
            else:
                message = get_template_module(
                    'bootstrap/flash_messages.html').community_success()
                category = 'success'
            flash(Markup(message), category)

        return redirect(url_for_index())
Пример #42
0
 def _apply_decoration(self, body):
     breadcrumbs = self._get_breadcrumbs()
     return '<div class="header">{}</div>\n<div class="main">{}<div>{}</div></div>\n{}'.format(
         self._get_header(), breadcrumbs, to_unicode(body),
         self._get_footer())
Пример #43
0
 def render(cls, regform, registration):
     event = registration.registration_form.event
     return Markup('<a href="{url}" title="{title}">{url}</a>'.format(url=event.getURL(),
                                                                      title=escape(to_unicode(event.title))))
Пример #44
0
 def setEmail(self, email, reindex=False):
     self.user.email = to_unicode(email)
Пример #45
0
 def setAddress(self, address):
     self.user.address = to_unicode(address)
Пример #46
0
 def _getBody(self, params):
     # Legacy handling for pages that do not use Jinja inheritance.
     tpl = u"{% extends 'events/management/base.html' %}{% block content %}{{ _body | safe }}{% endblock %}"
     body = to_unicode(self._getPageContent(params))
     return render_template_string(tpl, _body=body, **self._kwargs)
Пример #47
0
 def setTitle(self, title):
     self.user.title = to_unicode(title)
Пример #48
0
def _lower(text):
    return to_unicode(text).lower()
Пример #49
0
 def setSurName(self, surname, reindex=False):
     self.user.last_name = to_unicode(surname)
Пример #50
0
def make_email(to_list=None,
               cc_list=None,
               bcc_list=None,
               from_address=None,
               reply_address=None,
               attachments=None,
               subject=None,
               body=None,
               template=None,
               html=False):
    """Creates an email.

    The preferred way to specify the email content is using the
    `template` argument. To do so, use :func:`.get_template_module` on
    a template inheriting from ``emails/base.txt`` for text emails or
    ``emails/base.html`` for HTML emails.

    :param to_list: The recipient email or a collection of emails
    :param cc_list: The CC email or a collection of emails
    :param bcc_list: The BCC email or a collection of emails
    :param from_address: The sender address. Defaults to noreply.
    :param reply_address: The reply-to address or a collection of addresses.
                          Defaults to empty.
    :param attachments: A list of attachments. Each attachment can be
                        a `MIMEBase` subclass, a 3-tuple of the form
                        ``(filename, content, mimetype)``, or a 2-tuple
                        ``(filename, content)`` in which case the mime
                        type will be guessed from the file name.
    :param subject: The subject of the email.
    :param body: The body of the email:
    :param template: A template module containing ``get_subject`` and
                     ``get_body`` macros.
    :param html: ``True`` if the email body is HTML
    """
    if template is not None and (subject is not None or body is not None):
        raise ValueError("Only subject/body or template can be passed")

    if template:
        subject = template.get_subject()
        body = template.get_body()
    if config.DEBUG and '\n' in subject:
        raise ValueError('Email subject contains linebreaks')
    subject = re.sub(r'\s+', ' ', subject)
    if to_list is None:
        to_list = set()
    if cc_list is None:
        cc_list = set()
    if bcc_list is None:
        bcc_list = set()
    to_list = {to_list} if isinstance(to_list, basestring) else to_list
    cc_list = {cc_list} if isinstance(cc_list, basestring) else cc_list
    bcc_list = {bcc_list} if isinstance(bcc_list, basestring) else bcc_list
    reply_address = {reply_address} if isinstance(
        reply_address, basestring) else (reply_address or set())
    return {
        'to': set(map(to_unicode, to_list)),
        'cc': set(map(to_unicode, cc_list)),
        'bcc': set(map(to_unicode, bcc_list)),
        'from': to_unicode(from_address or config.NO_REPLY_EMAIL),
        'reply_to': set(map(to_unicode, reply_address)),
        'attachments': attachments or [],
        'subject': to_unicode(subject).strip(),
        'body': to_unicode(body).strip(),
        'html': html,
    }
Пример #51
0
 def setLang(self, lang):
     self.user.settings.set('lang', to_unicode(lang))
Пример #52
0
 def setTelephone(self, phone):
     self.user.phone = to_unicode(phone)
Пример #53
0
def handle_baddata(exc):
    return render_error(exc, _('Invalid or expired token'),
                        to_unicode(exc.message), 400)
Пример #54
0
 def setSecondaryEmails(self, emails, reindex=False):
     self.user.secondary_emails = {
         to_unicode(email.strip().lower())
         for email in emails
     }
Пример #55
0
 def __init__(self, text, pageNumber, style, part="", bulletText=None, frags=None, caseSensitive=1):
     Paragraph.__init__(self, to_unicode(text), style, part, bulletText, frags, caseSensitive)
     self._part = part
     self._pageNumber = pageNumber
Пример #56
0
 def addSecondaryEmail(self, email, reindex=False):
     return self.user.secondary_emails.add(to_unicode(
         email.strip().lower()))
Пример #57
0
def import_contributions_from_csv(event, f):
    """Import timetable contributions from a CSV file into an event."""
    reader = csv.reader(f.read().splitlines())
    contrib_data = []

    for num_row, row in enumerate(reader, 1):
        try:
            start_dt, duration, title, first_name, last_name, affiliation, email = \
                [to_unicode(value).strip() for value in row]
            email = email.lower()
        except ValueError:
            raise UserValueError(
                _('Row {}: malformed CSV data - please check that the number of columns is correct'
                  ).format(num_row))
        try:
            parsed_start_dt = event.tzinfo.localize(
                dateutil.parser.parse(start_dt)) if start_dt else None
        except ValueError:
            raise UserValueError(
                _("Row {row}: can't parse date: \"{date}\"").format(
                    row=num_row, date=start_dt))

        try:
            parsed_duration = timedelta(
                minutes=int(duration)) if duration else None
        except ValueError:
            raise UserValueError(
                _("Row {row}: can't parse duration: {duration}").format(
                    row=num_row, duration=duration))

        if not title:
            raise UserValueError(
                _("Row {}: contribution title is required").format(num_row))

        if email and not validate_email(email):
            raise UserValueError(
                _("Row {row}: invalid email address: {email}").format(
                    row=num_row, email=email))

        contrib_data.append({
            'start_dt':
            parsed_start_dt,
            'duration':
            parsed_duration or timedelta(minutes=20),
            'title':
            title,
            'speaker': {
                'first_name': first_name,
                'last_name': last_name,
                'affiliation': affiliation,
                'email': email
            }
        })

    # now that we're sure the data is OK, let's pre-allocate the friendly ids
    # for the contributions in question
    Contribution.allocate_friendly_ids(event, len(contrib_data))
    contributions = []
    all_changes = defaultdict(list)

    for contrib_fields in contrib_data:
        speaker_data = contrib_fields.pop('speaker')

        with track_time_changes() as changes:
            contribution = create_contribution(event,
                                               contrib_fields,
                                               extend_parent=True)

        contributions.append(contribution)
        for key, val in changes[event].viewitems():
            all_changes[key].append(val)

        email = speaker_data['email']
        if not email:
            continue

        # set the information of the speaker
        person = get_event_person(
            event, {
                'firstName': speaker_data['first_name'],
                'familyName': speaker_data['last_name'],
                'affiliation': speaker_data['affiliation'],
                'email': email
            })
        link = ContributionPersonLink(person=person, is_speaker=True)
        link.populate_from_dict({
            'first_name': speaker_data['first_name'],
            'last_name': speaker_data['last_name'],
            'affiliation': speaker_data['affiliation']
        })
        contribution.person_links.append(link)

    return contributions, all_changes
Пример #58
0
def test_to_unicode(input, output):
    assert to_unicode(input) == output
Пример #59
0
def handler(prefix, path):
    path = posixpath.join('/', prefix, path)
    clearCache()  # init fossil cache
    logger = Logger.get('httpapi')
    if request.method == 'POST':
        # Convert POST data to a query string
        queryParams = [(key, [x.encode('utf-8') for x in values])
                       for key, values in request.form.iterlists()]
        query = urllib.urlencode(queryParams, doseq=1)
        # we only need/keep multiple values so we can properly validate the signature.
        # the legacy code below expects a dict with just the first value.
        # if you write a new api endpoint that needs multiple values get them from
        # ``request.values.getlist()`` directly
        queryParams = {key: values[0] for key, values in queryParams}
    else:
        # Parse the actual query string
        queryParams = dict((key, value.encode('utf-8'))
                           for key, value in request.args.iteritems())
        query = request.query_string

    apiKey = get_query_parameter(queryParams, ['ak', 'apikey'], None)
    cookieAuth = get_query_parameter(queryParams, ['ca', 'cookieauth'],
                                     'no') == 'yes'
    signature = get_query_parameter(queryParams, ['signature'])
    timestamp = get_query_parameter(queryParams, ['timestamp'],
                                    0,
                                    integer=True)
    noCache = get_query_parameter(queryParams, ['nc', 'nocache'],
                                  'no') == 'yes'
    pretty = get_query_parameter(queryParams, ['p', 'pretty'], 'no') == 'yes'
    onlyPublic = get_query_parameter(queryParams, ['op', 'onlypublic'],
                                     'no') == 'yes'
    onlyAuthed = get_query_parameter(queryParams, ['oa', 'onlyauthed'],
                                     'no') == 'yes'
    scope = 'read:legacy_api' if request.method == 'GET' else 'write:legacy_api'

    if not request.headers.get('Authorization',
                               '').lower().startswith('basic '):
        try:
            oauth_valid, oauth_request = oauth.verify_request([scope])
            if not oauth_valid and oauth_request and oauth_request.error_message != 'Bearer token not found.':
                raise BadRequest('OAuth error: {}'.format(
                    oauth_request.error_message))
            elif g.get(
                    'received_oauth_token'
            ) and oauth_request.error_message == 'Bearer token not found.':
                raise BadRequest('OAuth error: Invalid token')
        except ValueError:
            # XXX: Dirty hack to workaround a bug in flask-oauthlib that causes it
            #      not to properly urlencode request query strings
            #      Related issue (https://github.com/lepture/flask-oauthlib/issues/213)
            oauth_valid = False
    else:
        oauth_valid = False

    # Get our handler function and its argument and response type
    hook, dformat = HTTPAPIHook.parseRequest(path, queryParams)
    if hook is None or dformat is None:
        raise NotFound

    # Disable caching if we are not just retrieving data (or the hook requires it)
    if request.method == 'POST' or hook.NO_CACHE:
        noCache = True

    ak = error = result = None
    ts = int(time.time())
    typeMap = {}
    status_code = None
    is_response = False
    try:
        used_session = None
        if cookieAuth:
            used_session = session
            if not used_session.user:  # ignore guest sessions
                used_session = None

        if apiKey or oauth_valid or not used_session:
            if not oauth_valid:
                # Validate the API key (and its signature)
                ak, enforceOnlyPublic = checkAK(apiKey, signature, timestamp,
                                                path, query)
                if enforceOnlyPublic:
                    onlyPublic = True
                # Create an access wrapper for the API key's user
                user = ak.user if ak and not onlyPublic else None
            else:  # Access Token (OAuth)
                at = load_token(oauth_request.access_token.access_token)
                user = at.user if at and not onlyPublic else None
            # Get rid of API key in cache key if we did not impersonate a user
            if ak and user is None:
                cacheKey = normalizeQuery(
                    path,
                    query,
                    remove=('_', 'ak', 'apiKey', 'signature', 'timestamp',
                            'nc', 'nocache', 'oa', 'onlyauthed'))
            else:
                cacheKey = normalizeQuery(path,
                                          query,
                                          remove=('_', 'signature',
                                                  'timestamp', 'nc', 'nocache',
                                                  'oa', 'onlyauthed'))
                if signature:
                    # in case the request was signed, store the result under a different key
                    cacheKey = 'signed_' + cacheKey
        else:
            # We authenticated using a session cookie.
            token = request.headers.get(
                'X-CSRF-Token', get_query_parameter(queryParams,
                                                    ['csrftoken']))
            if used_session.csrf_protected and used_session.csrf_token != token:
                raise HTTPAPIError('Invalid CSRF token', 403)
            user = used_session.user if not onlyPublic else None
            userPrefix = 'user-{}_'.format(used_session.user.id)
            cacheKey = userPrefix + normalizeQuery(
                path,
                query,
                remove=('_', 'nc', 'nocache', 'ca', 'cookieauth', 'oa',
                        'onlyauthed', 'csrftoken'))

        # Bail out if the user requires authentication but is not authenticated
        if onlyAuthed and not user:
            raise HTTPAPIError('Not authenticated', 403)

        addToCache = not hook.NO_CACHE
        cache = GenericCache('HTTPAPI')
        cacheKey = RE_REMOVE_EXTENSION.sub('', cacheKey)
        if not noCache:
            obj = cache.get(cacheKey)
            if obj is not None:
                result, extra, ts, complete, typeMap = obj
                addToCache = False
        if result is None:
            g.current_api_user = user
            # Perform the actual exporting
            res = hook(user)
            if isinstance(res, current_app.response_class):
                addToCache = False
                is_response = True
                result, extra, complete, typeMap = res, {}, True, {}
            elif isinstance(res, tuple) and len(res) == 4:
                result, extra, complete, typeMap = res
            else:
                result, extra, complete, typeMap = res, {}, True, {}
        if result is not None and addToCache:
            ttl = api_settings.get('cache_ttl')
            if ttl > 0:
                cache.set(cacheKey, (result, extra, ts, complete, typeMap),
                          ttl)
    except HTTPAPIError as e:
        error = e
        if e.getCode():
            status_code = e.getCode()

    if result is None and error is None:
        # TODO: usage page
        raise NotFound
    else:
        if ak and error is None:
            # Commit only if there was an API key and no error
            norm_path, norm_query = normalizeQuery(path,
                                                   query,
                                                   remove=('signature',
                                                           'timestamp'),
                                                   separate=True)
            uri = to_unicode('?'.join(filter(None, (norm_path, norm_query))))
            ak.register_used(request.remote_addr, uri, not onlyPublic)
            db.session.commit()
        else:
            # No need to commit stuff if we didn't use an API key (nothing was written)
            # XXX do we even need this?
            db.session.rollback()

        # Log successful POST api requests
        if error is None and request.method == 'POST':
            logger.info('API request: %s?%s', path, query)
        if is_response:
            return result
        serializer = Serializer.create(dformat,
                                       query_params=queryParams,
                                       pretty=pretty,
                                       typeMap=typeMap,
                                       **hook.serializer_args)
        if error:
            if not serializer.schemaless:
                # if our serializer has a specific schema (HTML, ICAL, etc...)
                # use JSON, since it is universal
                serializer = Serializer.create('json')

            result = fossilize(error)
        else:
            if serializer.encapsulate:
                result = fossilize(
                    HTTPAPIResult(result, path, query, ts, complete, extra),
                    IHTTPAPIExportResultFossil)
                del result['_fossil']

        try:
            data = serializer(result)
            response = current_app.make_response(data)
            content_type = serializer.get_response_content_type()
            if content_type:
                response.content_type = content_type
            if status_code:
                response.status_code = status_code
            return response
        except Exception:
            logger.exception('Serialization error in request %s?%s', path,
                             query)
            raise
Пример #60
0
 def __init__(self, group_id):
     self.id = to_unicode(group_id).encode('utf-8')