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
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
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
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
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
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 ]
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)
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)
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)
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
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
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)
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)
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)
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' )
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]
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)]
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)