Ejemplo n.º 1
0
def clone_into_event(source_event, target_event, cloners):
    """Clone data into an existing event.

    Runs all required cloners.

    :param source_event: The `Event` to clone data from;
    :param target_event: The `Event` to clone data into;
    :param cloners: A set containing the names of all enabled cloners.
    """

    # Run the modular cloning system
    g.importing_event = True
    EventCloner.run_cloners(source_event,
                            target_event,
                            cloners,
                            event_exists=True)
    del g.importing_event
    signals.event.imported.send(target_event, source_event=source_event)
    cloner_classes = {c.name: c for c in get_event_cloners().values()}
    target_event.log(EventLogRealm.event,
                     LogKind.change,
                     'Event',
                     'Data imported',
                     session.user,
                     data={
                         'Modules':
                         ', '.join(
                             orig_string(cloner_classes[c].friendly_name)
                             for c in cloners
                             if not cloner_classes[c].is_internal)
                     })

    return target_event
Ejemplo n.º 2
0
    def clone(self, startDate):
        # startDate is in the timezone of the event
        old_event = self.as_event
        start_dt = old_event.tzinfo.localize(startDate).astimezone(utc)
        end_dt = start_dt + old_event.duration
        data = {
            'start_dt': start_dt,
            'end_dt': end_dt,
            'timezone': old_event.timezone,
            'title': old_event.title,
            'description': old_event.description,
            'visibility': old_event.visibility
        }
        event = create_event(old_event.category, old_event.type_, data,
                             features=features_event_settings.get(self, 'enabled'),
                             add_creator_as_manager=False)

        # Run the new modular cloning system
        EventCloner.run_cloners(old_event, event)
        signals.event.cloned.send(old_event, new_event=event)

        # Grant access to the event creator -- must be done after modular cloners
        # since cloning the event ACL would result in a duplicate entry
        with event.logging_disabled:
            event.update_principal(session.user, full_access=True)

        return event.as_legacy
Ejemplo n.º 3
0
def clone_event(event, start_dt, cloners, category=None):
    """Clone an event on a given date/time.

    Runs all required cloners.

    :param start_dt: The start datetime of the new event;
    :param cloners: A set containing the names of all enabled cloners;
    :param category: The `Category` the new event will be created in.
    """
    end_dt = start_dt + event.duration
    data = {
        'start_dt': start_dt,
        'end_dt': end_dt,
        'timezone': event.timezone,
        'title': event.title,
        'description': event.description,
    }
    new_event = create_event(category or event.category, event.type_, data,
                             features=features_event_settings.get(event, 'enabled'),
                             add_creator_as_manager=False)

    # Run the modular cloning system
    EventCloner.run_cloners(event, new_event, cloners)
    signals.event.cloned.send(event, new_event=new_event)

    # Grant access to the event creator -- must be done after modular cloners
    # since cloning the event ACL would result in a duplicate entry
    with new_event.logging_disabled:
        new_event.update_principal(session.user, full_access=True)

    return new_event
Ejemplo n.º 4
0
def clone_event(event, start_dt, cloners, category=None):
    """Clone an event on a given date/time.

    Runs all required cloners.

    :param start_dt: The start datetime of the new event;
    :param cloners: A set containing the names of all enabled cloners;
    :param category: The `Category` the new event will be created in.
    """
    end_dt = start_dt + event.duration
    data = {
        'start_dt': start_dt,
        'end_dt': end_dt,
        'timezone': event.timezone,
        'title': event.title,
        'description': event.description,
    }
    new_event = create_event(category or event.category,
                             event.type_,
                             data,
                             features=features_event_settings.get(
                                 event, 'enabled'),
                             add_creator_as_manager=False)

    # Run the modular cloning system
    EventCloner.run_cloners(event, new_event, cloners)
    signals.event.cloned.send(event, new_event=new_event)

    # Grant access to the event creator -- must be done after modular cloners
    # since cloning the event ACL would result in a duplicate entry
    with new_event.logging_disabled:
        new_event.update_principal(session.user, full_access=True)

    return new_event
Ejemplo n.º 5
0
def test_registration_clone(dummy_event, dummy_regform, create_event, dummy_user):
    set_feature_enabled(dummy_event, 'registration', True)

    assert dummy_regform.event == dummy_event
    assert dummy_event.registrations.one().user == dummy_user
    assert dummy_event.registrations.one().checked_in

    copied_event = create_event()
    EventCloner.run_cloners(dummy_event, copied_event, {'registrations', 'registration_forms'})
    copied_registration = copied_event.registrations.one()

    assert copied_registration.event == copied_event
    assert copied_registration.user == dummy_user
    assert not copied_registration.checked_in
Ejemplo n.º 6
0
    def __init__(self, event, set_defaults=False, **kwargs):
        options = EventCloner.get_cloners(event)
        visible_options = filter(attrgetter('is_visible'), options)
        default_selected_items = kwargs.get(
            'selected_items',
            [option.name for option in options if option.is_default])

        if set_defaults:
            default_category = kwargs['category'][
                'id'] if 'category' in kwargs else None
            form_params = {
                'repeatability':
                request.form.get('repeatability',
                                 kwargs.pop('repeatability', None)),
                'selected_items': (request.form.getlist('selected_items')
                                   or default_selected_items),
                'category':
                request.form.get('category', default_category),
                'csrf_token':
                request.form.get('csrf_token')
            }
            kwargs['formdata'] = ImmutableMultiDict(form_params)

        super(CloneContentsForm, self).__init__(**kwargs)
        self.selected_items.choices = [(option.name, option.friendly_name)
                                       for option in visible_options]
        self.selected_items.disabled_choices = [
            option.name for option in visible_options
            if not option.is_available
        ]
Ejemplo n.º 7
0
    def _process(self):
        step = int(request.form.get('step', 1))
        form = self._form_for_step(step, set_defaults=True)
        prev_form = self._form_for_step(step - 1)

        if prev_form and not prev_form.validate():
            form = prev_form
            step = step - 1

        elif step > 2:
            # last step - perform actual cloning
            form = ImportContentsForm(self.source_event, self.event)

            if form.validate_on_submit():
                updated_event = clone_into_event(self.source_event, self.event,
                                                 set(form.selected_items.data))
                flash(_('Import successful!'), 'success')
                return jsonify_data(redirect=url_for(
                    'event_management.settings', updated_event),
                                    flash=False)
            else:
                # back to step 2, since there's been an error
                step = 2
        dependencies = {
            c.name: {
                'requires': list(c.requires_deep),
                'required_by': list(c.required_by_deep)
            }
            for c in EventCloner.get_cloners(self.event)
        }
        return jsonify_template('events/management/import_event.html',
                                event=self.event,
                                step=step,
                                form=form,
                                cloner_dependencies=dependencies)
Ejemplo n.º 8
0
    def _process(self):
        step = int(request.form.get('step', 1))
        tpl_args = {}
        form = self._form_for_step(step, set_defaults=True)
        prev_form = self._form_for_step(step - 1)

        if prev_form and not prev_form.validate():
            form = prev_form
            step = step - 1

        if step == 4:
            tpl_args.update({
                'step_title':
                dict(CLONE_REPEAT_CHOICES)[request.form['repeatability']],
            })
        elif step > 4:
            # last step - perform actual cloning
            form = REPEAT_FORM_MAP[request.form['repeatability']](
                self.event_new)

            if form.validate_on_submit():
                if form.repeatability.data == 'once':
                    dates = [form.start_dt.data]
                else:
                    clone_calculator = get_clone_calculator(
                        form.repeatability.data, self.event_new)
                    dates = clone_calculator.calculate(request.form)
                clones = [
                    clone_event(self.event_new, start_dt,
                                set(form.selected_items.data),
                                form.category.data) for start_dt in dates
                ]
                if len(clones) == 1:
                    flash(_('Welcome to your cloned event!'), 'success')
                    return jsonify_data(redirect=url_for(
                        'event_management.settings', clones[0]),
                                        flash=False)
                else:
                    flash(
                        _('{} new events created.').format(len(dates)),
                        'success')
                    return jsonify_data(redirect=form.category.data.url,
                                        flash=False)
            else:
                # back to step 4, since there's been an error
                step = 4
        dependencies = {
            c.name: {
                'requires': list(c.requires_deep),
                'required_by': list(c.required_by_deep)
            }
            for c in EventCloner.get_cloners(self.event_new)
        }
        return jsonify_template('events/management/clone_event.html',
                                event=self.event_new,
                                step=step,
                                form=form,
                                cloner_dependencies=dependencies,
                                **tpl_args)
Ejemplo n.º 9
0
 def _getPageContent(self, params):
     p = conferences.WConferenceClone( self._conf )
     pars = {
         "cancelURL": urlHandlers.UHConfModifTools.getURL(self._conf),
         "cloning": urlHandlers.UHConfPerformCloning.getURL(self._conf),
         "cloneOptions": EventCloner.get_form_items(self._conf.as_event).encode('utf-8')
     }
     return p.getHTML(pars)
Ejemplo n.º 10
0
def clone_event(event,
                n_occurrence,
                start_dt,
                cloners,
                category=None,
                refresh_users=False):
    """Clone an event on a given date/time.

    Runs all required cloners.

    :param n_occurrence: The 1-indexed number of the occurrence, if this is a "recurring" clone, otherwise `0`
    :param start_dt: The start datetime of the new event;
    :param cloners: A set containing the names of all enabled cloners;
    :param category: The `Category` the new event will be created in.
    :aparam refresh_users: Whether `EventPerson` data should be updated from
                           their linked `User` object
    """
    end_dt = start_dt + event.duration
    data = {
        'start_dt': start_dt,
        'end_dt': end_dt,
        'timezone': event.timezone,
        'title': event.title,
        'description': event.description,
        'own_map_url': event.own_map_url
    }
    new_event = create_event(category or event.category,
                             event.type_,
                             data,
                             features=features_event_settings.get(
                                 event, 'enabled'),
                             add_creator_as_manager=False,
                             cloning=True)

    # Run the modular cloning system
    EventCloner.run_cloners(event, new_event, cloners, n_occurrence)
    if refresh_users:
        new_event.refresh_event_persons(notify=False)
    signals.event.cloned.send(event, new_event=new_event)

    # Grant access to the event creator -- must be done after modular cloners
    # since cloning the event ACL would result in a duplicate entry
    with new_event.logging_disabled:
        new_event.update_principal(session.user, full_access=True)

    return new_event
Ejemplo n.º 11
0
def clone_into_event(source_event, target_event, cloners):
    """Clone data into an existing event.

    Runs all required cloners.

    :param source_event: The `Event` to clone data from;
    :param target_event: The `Event` to clone data into;
    :param cloners: A set containing the names of all enabled cloners.
    """

    # Run the modular cloning system
    EventCloner.run_cloners(source_event,
                            target_event,
                            cloners,
                            event_exists=True)
    signals.event.imported.send(target_event, source_event=source_event)

    return target_event
Ejemplo n.º 12
0
 def _getPageContent(self, params):
     p = conferences.WConferenceClone(self._conf)
     pars = {
         "cancelURL": urlHandlers.UHConfModifTools.getURL(self._conf),
         "cloning": urlHandlers.UHConfPerformCloning.getURL(self._conf),
         "startTime": self._conf.getUnixStartDate(),
         "cloneOptions": ''
     }
     pars['cloneOptions'] += EventCloner.get_form_items(self._conf.as_event).encode('utf-8')
     return p.getHTML(pars)
Ejemplo n.º 13
0
 def _getPageContent(self, params):
     p = conferences.WConferenceClone(self._conf)
     pars = {
         "cancelURL": urlHandlers.UHConfModifTools.getURL(self._conf),
         "cloning": urlHandlers.UHConfPerformCloning.getURL(self._conf),
         "cloneOptions": ''
     }
     pars['cloneOptions'] += EventCloner.get_form_items(
         self._conf.as_event).encode('utf-8')
     return p.getHTML(pars)
Ejemplo n.º 14
0
 def _getPageContent(self, params):
     p = conferences.WConferenceClone(self._conf)
     pars = {
         "cancelURL":
         urlHandlers.UHConfModifTools.getURL(self._conf),
         "cloning":
         urlHandlers.UHConfPerformCloning.getURL(self._conf),
         "startTime":
         self._conf.getUnixStartDate(),
         "cloneOptions":
         EventCloner.get_form_items(self._conf.as_event).encode('utf-8')
     }
     return p.getHTML(pars)
Ejemplo n.º 15
0
    def __init__(self,
                 source_event,
                 target_event,
                 set_defaults=False,
                 **kwargs):
        cloners = EventCloner.get_cloners(source_event)
        visible_options = [
            cloner for cloner in cloners
            if cloner.is_visible and not cloner.new_event_only
        ]
        conflicts = {
            cloner.name: cloner.get_conflicts(target_event)
            for cloner in cloners
        }
        cloners_with_conflicts = {
            name
            for name in conflicts if conflicts[name]
        }

        if set_defaults:
            form_params = {
                'source_event_url':
                request.form.get('source_event_url',
                                 kwargs.pop('source_event_url', None)),
                'selected_items':
                request.form.getlist('selected_items'),
                'csrf_token':
                request.form.get('csrf_token')
            }
            kwargs['formdata'] = ImmutableMultiDict(form_params)

        super().__init__(**kwargs)
        self.selected_items.choices = [(option.name, option.friendly_name)
                                       for option in visible_options]
        # We disable all cloners that are not available, handle only cloning to new events,
        # have conflicts with target_event or any of their dependencies have conflicts with target_event
        disabled_choices = []
        reasons = {}
        for option in visible_options:
            if not option.is_available:
                disabled_choices.append(option.name)
                reasons[option.name] = _('There is nothing to import')
            elif conflict := conflicts[option.name]:
                disabled_choices.append(option.name)
                reasons[option.name] = '\n'.join(conflict)
            elif cloners_with_conflicts & option.requires_deep:
                disabled_choices.append(option.name)
                reasons[option.name] = _(
                    'This option depends on other options which are unavailable'
                )
Ejemplo n.º 16
0
    def __init__(self, event, set_defaults=False, **kwargs):
        options = EventCloner.get_cloners(event)
        visible_options = filter(attrgetter('is_visible'), options)
        default_selected_items = kwargs.get('selected_items', [option.name for option in options if option.is_default])

        if set_defaults:
            default_category = kwargs['category']['id'] if 'category' in kwargs else None
            form_params = {
                'repeatability': request.form.get('repeatability', kwargs.pop('repeatability', None)),
                'selected_items': (request.form.getlist('selected_items') or default_selected_items),
                'category': request.form.get('category', default_category),
                'csrf_token': request.form.get('csrf_token')
            }
            kwargs['formdata'] = ImmutableMultiDict(form_params)

        super(CloneContentsForm, self).__init__(**kwargs)
        self.selected_items.choices = [(option.name, option.friendly_name) for option in visible_options]
        self.selected_items.disabled_choices = [option.name for option in visible_options if not option.is_available]
Ejemplo n.º 17
0
    def __init__(self, source_event, target_event, set_defaults=False, **kwargs):
        cloners = EventCloner.get_cloners(source_event)
        visible_options = [cloner for cloner in cloners if cloner.is_visible and not cloner.new_event_only]
        conflicts = {cloner.name: cloner.has_conflicts(target_event) for cloner in cloners}

        if set_defaults:
            form_params = {
                'source_event_url': request.form.get('source_event_url', kwargs.pop('source_event_url', None)),
                'selected_items': request.form.getlist('selected_items'),
                'csrf_token': request.form.get('csrf_token')
            }
            kwargs['formdata'] = ImmutableMultiDict(form_params)

        super().__init__(**kwargs)
        self.selected_items.choices = [(option.name, option.friendly_name) for option in visible_options]
        # We disable all cloners that are not available, handle only cloning to new events,
        # have conflicts with target_event or any of their dependencies has conflicts with target_event
        self.selected_items.disabled_choices = [option.name for option in visible_options if not option.is_available
                                                or conflicts[option.name]
                                                or any(conflicts[dep] for dep in option.requires)]
Ejemplo n.º 18
0
    def _process(self):
        step = int(request.form.get('step', 1))
        tpl_args = {}
        form = self._form_for_step(step, set_defaults=True)
        prev_form = self._form_for_step(step - 1)

        if prev_form and not prev_form.validate():
            form = prev_form
            step = step - 1

        if step == 4:
            tpl_args.update({
                'step_title': dict(CLONE_REPEAT_CHOICES)[request.form['repeatability']],
            })
        elif step > 4:
            # last step - perform actual cloning
            form = REPEAT_FORM_MAP[request.form['repeatability']](self.event)

            if form.validate_on_submit():
                if form.repeatability.data == 'once':
                    dates = [form.start_dt.data]
                else:
                    clone_calculator = get_clone_calculator(form.repeatability.data, self.event)
                    dates = clone_calculator.calculate(request.form)
                clones = [clone_event(self.event, start_dt, set(form.selected_items.data), form.category.data)
                          for start_dt in dates]
                if len(clones) == 1:
                    flash(_('Welcome to your cloned event!'), 'success')
                    return jsonify_data(redirect=url_for('event_management.settings', clones[0]), flash=False)
                else:
                    flash(_('{} new events created.').format(len(dates)), 'success')
                    return jsonify_data(redirect=form.category.data.url, flash=False)
            else:
                # back to step 4, since there's been an error
                step = 4
        dependencies = {c.name: {'requires': list(c.requires_deep), 'required_by': list(c.required_by_deep)}
                        for c in EventCloner.get_cloners(self.event)}
        return jsonify_template('events/management/clone_event.html', event=self.event, step=step, form=form,
                                cloner_dependencies=dependencies, **tpl_args)