def _redirect_legacy_id(): if not request.view_args or request.endpoint in _non_standard_id_endpoints: return key = event_id = None if 'confId' in request.view_args: key = 'confId' event_id = request.view_args['confId'] elif 'event_id' in request.view_args: key = 'event_id' event_id = request.view_args['event_id'] if event_id is None or not is_legacy_id(event_id): return if request.method != 'GET': raise BadRequest('Unexpected non-GET request with legacy event ID') mapping = LegacyEventMapping.query.filter_by( legacy_event_id=event_id).first() if mapping is None: raise NotFound(f'Legacy event {event_id} does not exist') request.view_args[key] = str(mapping.event_id) return redirect( url_for(request.endpoint, **dict(request.args.to_dict(), **request.view_args)), 301)
def create_event(self): if is_legacy_id(self.conf.id): event_id = int(self.gen_event_id()) self.is_legacy = True else: event_id = int(self.conf.id) try: parent_category = self.importer.global_ns.legacy_category_ids[ self.conf._Conference__owners[0].id] except (IndexError, KeyError): self.importer.print_error('Event has no category!', event_id=self.conf.id) if self.importer.migrate_broken_events: parent_category = self.lostandfound_category else: raise SkipEvent title = convert_to_unicode(getattr(self.conf, 'title', '')) or '(no title)' self.importer.print_success(title) tz = self.conf.__dict__.get('timezone', 'UTC') self.event = Event( id=event_id, title=title, description=convert_to_unicode(self.conf.description) or '', timezone=tz, start_dt=self._fix_naive(self.conf.startDate), end_dt=self._fix_naive(self.conf.endDate), is_locked=self.conf._closed, category=parent_category, is_deleted=False)
def _migrate_category(self, old_cat, position): # unlimited visibility is 999 but we have a 994 for some reason.. since nobody # has 900 levels of nesting we can just go for that threshold instead visibility = None if old_cat._visibility > 900 else old_cat._visibility if visibility == 0: self.print_warning( "Raising visibility from 'invisible' to 'category-only'", event_id=old_cat.id) visibility = 1 emails = re.split( r'[\s;,]+', convert_to_unicode(getattr(old_cat, '_notifyCreationList', ''))) emails = {sanitize_email(email).lower() for email in emails} emails = sorted(email for email in emails if is_valid_mail(email, False)) default_themes = self._process_default_themes(old_cat) title = self._fix_title(convert_to_unicode(old_cat.name), old_cat.id) if is_legacy_id(old_cat.id): # if category has a legacy (non-numeric) ID, generate a new ID # and establish a mapping (for URL redirection) new_id = self.gen_categ_id() db.session.add( LegacyCategoryMapping(legacy_category_id=old_cat.id, category_id=new_id)) self.print_success('%[white!]{:6s}%[reset] -> %[cyan]{}'.format( old_cat.id, new_id)) else: new_id = int(old_cat.id) if hasattr(old_cat, '_timezone'): tz_name = old_cat._timezone else: tz_name = self.makac_info._timezone cat = Category(id=int(new_id), position=position, title=title, description=convert_to_unicode(old_cat.description), visibility=visibility, timezone=convert_to_unicode(tz_name), event_creation_notification_emails=emails, default_event_themes=default_themes, suggestions_disabled=getattr(old_cat, '_suggestions_disabled', False)) if not self.quiet: self.print_success(cat.title, event_id=cat.id) if old_cat._icon: self._process_icon(cat, old_cat._icon) self._process_protection(cat, old_cat) self.migrate_category_attachments(cat, old_cat) cat.children = [(self._migrate_category(old_subcat, i)) for i, old_subcat in enumerate( sorted(old_cat.subcategories.itervalues(), key=attrgetter('_order')), 1)] # add to user favorites for user in self.global_ns.user_favorite_categories[old_cat.id]: user.favorite_categories.add(cat) self.global_ns.legacy_category_ids[old_cat.id] = cat return cat
def event_or_shorturl(confId, shorturl_namespace=False, force_overview=False): func = None event_ = Event.get(int(confId)) if confId.isdigit() else None if event_ and event_.is_deleted: raise NotFound(_('This event has been deleted.')) elif event_: # For obvious reasons an event id always comes first. # If it's used within the short url namespace we redirect to the event namespace, otherwise # we call the RH to display the event if shorturl_namespace: func = lambda: redirect(event_.url) else: request.view_args['confId'] = int(request.view_args['confId']) func = lambda: RHDisplayEvent().process() else: shorturl_event = (Event.query .filter(db.func.lower(Event.url_shortcut) == confId.lower(), ~Event.is_deleted) .one_or_none()) if (shorturl_namespace or config.ROUTE_OLD_URLS) and shorturl_event: if shorturl_namespace: # Correct namespace => redirect to the event func = lambda: redirect(shorturl_event.url) else: # Old event namespace => 301-redirect to the new shorturl first to get Google etc. to update it func = lambda: redirect(shorturl_event.short_url, 301) elif is_legacy_id(confId): mapping = LegacyEventMapping.find_first(legacy_event_id=confId) if mapping is not None: url = url_for('events.display', confId=mapping.event_id) func = lambda: redirect(url, 301) if func is None: raise NotFound(_('An event with this ID/shortcut does not exist.')) return func()
def _extract_event_id(self, link_url): parsed_url = urlparse.urlparse(link_url) path = parsed_url.path query = parsed_url.query if query: parsed_qs = urlparse.parse_qs(query) if not parsed_qs: event_id = query else: event_id = parsed_qs['confId'][0] if is_legacy_id(event_id): try: event_id = self.legacy_event_mapping[event_id] except KeyError: return None else: match = re.match(r'/(?:event|e)/(?P<event_id>\d+)/material/(?P<material_id>\d+)/?', path) if match is not None: folder = LegacyAttachmentFolderMapping.find(event_id=match.group('event_id'), contribution_id=None, session_id=None, subcontribution_id=None, material_id=match.group('material_id')).one().folder return self._extract_event_id(folder.attachments[0].link_url) match = re.match(r'/(?:event|e)/(?P<event_id>\d+)/?', path) if match is None: print path event_id = match.group('event_id') return int(event_id)
def event_or_shorturl(confId, shorturl_namespace=False, force_overview=False): func = None event_ = Event.get(int(confId)) if confId.isdigit() else None if event_ and event_.is_deleted: raise NotFound(_('This event has been deleted.')) elif event_: # For obvious reasons an event id always comes first. # If it's used within the short url namespace we redirect to the event namespace, otherwise # we call the RH to display the event if shorturl_namespace: func = lambda: redirect(event_.url) else: request.view_args['confId'] = int(request.view_args['confId']) func = lambda: RHDisplayEvent().process() else: shorturl_event = (Event.query.filter( db.func.lower(Event.url_shortcut) == confId.lower(), ~Event.is_deleted).one_or_none()) if (shorturl_namespace or config.ROUTE_OLD_URLS) and shorturl_event: if shorturl_namespace: # Correct namespace => redirect to the event func = lambda: redirect(shorturl_event.url) else: # Old event namespace => 301-redirect to the new shorturl first to get Google etc. to update it func = lambda: redirect(shorturl_event.short_url, 301) elif is_legacy_id(confId): mapping = LegacyEventMapping.find_first(legacy_event_id=confId) if mapping is not None: url = url_for('events.display', confId=mapping.event_id) func = lambda: redirect(url, 301) if func is None: raise NotFound(_('An event with this ID/shortcut does not exist.')) return func()
def event_or_shorturl(event_id, shorturl_namespace=False, force_overview=False): event = Event.get(int(event_id)) if event_id.isdigit() and (event_id[0] != '0' or event_id == '0') else None if event and event.is_deleted: raise NotFound(_('This event has been deleted.')) elif event: # For obvious reasons an event id always comes first. # If it's used within the short url namespace we redirect to the event namespace, otherwise # we call the RH to display the event if shorturl_namespace: return redirect(event.url) elif not request.path.endswith('/'): return redirect(event.url, 301) else: request.view_args['event_id'] = int(event_id) return RHDisplayEvent().process() else: shorturl_event = (Event.query .filter(db.func.lower(Event.url_shortcut) == event_id.lower(), ~Event.is_deleted) .one_or_none()) if (shorturl_namespace or config.ROUTE_OLD_URLS) and shorturl_event: if shorturl_namespace: # Correct namespace => redirect to the event return redirect(shorturl_event.url) else: # Old event namespace => 301-redirect to the new shorturl first to get Google etc. to update it return redirect(shorturl_event.short_url, 301) elif is_legacy_id(event_id): mapping = LegacyEventMapping.query.filter_by(legacy_event_id=event_id).first() if mapping is not None: url = url_for('events.display', event_id=mapping.event_id) return redirect(url, 301) raise NotFound(_('An event with this ID/shortcut does not exist.'))
def _extract_event_id(self, link_url): parsed_url = urlparse.urlparse(link_url) path = parsed_url.path query = parsed_url.query if query: parsed_qs = urlparse.parse_qs(query) if not parsed_qs: event_id = query else: event_id = parsed_qs['confId'][0] if is_legacy_id(event_id): try: event_id = self.legacy_event_mapping[event_id] except KeyError: return None else: match = re.match( r'/(?:event|e)/(?P<event_id>\d+)/material/(?P<material_id>\d+)/?', path) if match is not None: folder = (LegacyAttachmentFolderMapping.query.filter_by( event_id=match.group('event_id'), contribution_id=None, session_id=None, subcontribution_id=None, material_id=match.group('material_id')).one().folder) return self._extract_event_id(folder.attachments[0].link_url) match = re.match(r'/(?:event|e)/(?P<event_id>\d+)/?', path) event_id = match.group('event_id') return int(event_id)
def migrate(self): print cformat('%{white!}migrating static sites') for item in committing_iterator(chain.from_iterable( self.zodb_root['modules']['offlineEvents']._idxConf.itervalues())): event_id = item.conference.id if is_legacy_id(event_id): print cformat('%{red!}!!!%{reset} ' '%{white!}{0:6s}%{reset} %{yellow!}Event has non-numeric/broken ID').format(event_id) continue if event_id not in self.zodb_root['conferences']: print cformat('%{red!}!!!%{reset} ' '%{white!}{0:6s}%{reset} %{yellow!}Event deleted, skipping static site').format(event_id) continue event_id = int(event_id) user = self._get_user(item.avatar.id) state = STATE_MAPPING[item.status] requested_dt = item.requestTime file_name, file_path = self._get_file_data(item.file) if file_path is None and state == StaticSiteState.success: print cformat('%{yellow!}!!!%{reset} %{white!}{0:6d}%{reset} ' '%{yellow!}file missing, marking static site as expired.').format(event_id) state = StaticSite.expired static_site = StaticSite(creator=user, event_id=event_id, state=state, requested_dt=requested_dt) if static_site.state == StaticSiteState.success: static_site.path = file_path db.session.add(static_site) print cformat('%{green}+++%{reset} %{white!}{0.event_id:6d}%{reset} ' '%{cyan}{0}%{reset}').format(static_site)
def _get_categories(self): # we modify the categories dict so we can't iterate over it while doing so cats = self.flushing_iterator( self.zodb_root['categories'].itervalues()) cats = verbose_iterator(cats, len(self.zodb_root['categories']), attrgetter('id'), attrgetter('name')) return [ cat for cat in cats if is_legacy_id(cat.id) or hasattr(cat, '_old_id') ]
def _get_events(self): # we modify the conferences dict so we can't iterate over it while doing so events = self.flushing_iterator( self.zodb_root['conferences'].itervalues()) events = verbose_iterator(events, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title')) return [ event for event in events if is_legacy_id(event.id) or hasattr(event, '_old_id') ]
def getById(self, id, quiet=False): id = str(id) if is_legacy_id(id): mapping = LegacyEventMapping.find_first(legacy_event_id=id) id = str(mapping.event_id) if mapping is not None else None event = self._getIdx().get(id) if id is not None else None if event is None and not quiet: raise NotFoundError( _("The event with id '{}' does not exist or has been deleted" ).format(id), title=_("Event not found")) return event
def migrate_event_alarms(self): print cformat('%{white!}migrating event alarms/reminders') sent_threshold = now_utc() - timedelta(days=1) for event, alarm in committing_iterator(self._iter_alarms()): if is_legacy_id(event.id): print cformat( '%{red!}!!!%{reset} ' '%{white!}{:6s}%{reset} %{yellow!}Event has non-numeric/broken ID' ).format(event.id) continue elif not alarm.startDateTime: print cformat( '%{red!}!!!%{reset} ' '%{white!}{:6s}%{reset} %{yellow!}Alarm has no start time' ).format(event.id) continue start_dt = self._dt_with_tz(alarm.startDateTime).replace( second=0, microsecond=0) if not hasattr(alarm, 'status'): # Those ancient alarms can be safely assumed to be sent is_sent = True else: is_sent = alarm.status not in {1, 2} # not spooled/queued is_overdue = False if not is_sent and start_dt < sent_threshold: is_sent = True is_overdue = True recipients = filter( None, {convert_to_unicode(x).strip().lower() for x in alarm.toAddr}) reminder = EventReminder( event_id=int(event.id), creator_id=Config.getInstance().getJanitorUserId(), created_dt=alarm.createdOn, scheduled_dt=start_dt, is_sent=is_sent, event_start_delta=getattr(alarm, '_relative', None), recipients=recipients, send_to_participants=alarm.toAllParticipants, include_summary=alarm.confSumary, reply_to_address=convert_to_unicode( alarm.fromAddr).strip().lower(), message=convert_to_unicode(alarm.note).strip()) db.session.add(reminder) status = (cformat('%{red!}OVERDUE%{reset}') if is_overdue else cformat('%{green!}SENT%{reset}') if is_sent else cformat('%{yellow}PENDING%{reset}')) print cformat( '%{green}+++%{reset} ' '%{white!}{:6s}%{reset} %{cyan}{}%{reset} {}').format( event.id, reminder.scheduled_dt, status)
def _clean_args(kwargs): if 'event_id' not in kwargs: raise NotFound if is_legacy_id(kwargs['event_id']): mapping = LegacyEventMapping.find(legacy_event_id=kwargs['event_id']).first_or_404() kwargs['event_id'] = mapping.event_id if 'contrib_id' in kwargs: kwargs['contribution_id'] = kwargs.pop('contrib_id') if 'subcontrib_id' in kwargs: kwargs['subcontribution_id'] = kwargs.pop('subcontrib_id') # extension is just to make the links prettier kwargs.pop('ext', None) # session id is only used for actual sessions, not for stuff inside them if 'contribution_id' in kwargs: kwargs.pop('session_id', None)
def _redirect_legacy_id(): if not request.view_args: return categ_id = request.view_args.get('categId') if categ_id is None or not is_legacy_id(categ_id): return if request.method != 'GET': raise BadRequest('Unexpected non-GET request with legacy category ID') mapping = LegacyCategoryMapping.find_first(legacy_category_id=categ_id) if mapping is None: raise NotFound('Legacy category {} does not exist'.format(categ_id)) request.view_args['categId'] = unicode(mapping.category_id) return redirect(url_for(request.endpoint, **dict(request.args.to_dict(), **request.view_args)), 301)
def migrate(self): print cformat('%{white!}migrating static sites') for item in committing_iterator( chain.from_iterable(self.zodb_root['modules'] ['offlineEvents']._idxConf.itervalues())): event_id = item.conference.id if is_legacy_id(event_id): print cformat( '%{red!}!!!%{reset} ' '%{white!}{0:6s}%{reset} %{yellow!}Event has non-numeric/broken ID' ).format(event_id) continue if event_id not in self.zodb_root['conferences']: print cformat( '%{red!}!!!%{reset} ' '%{white!}{0:6s}%{reset} %{yellow!}Event deleted, skipping static site' ).format(event_id) continue event_id = int(event_id) user = self._get_user(item.avatar.id) state = STATE_MAPPING[item.status] requested_dt = item.requestTime file_name, file_path = self._get_file_data(item.file) if file_path is None and state == StaticSiteState.success: print cformat( '%{yellow!}!!!%{reset} %{white!}{0:6d}%{reset} ' '%{yellow!}file missing, marking static site as expired.' ).format(event_id) state = StaticSite.expired static_site = StaticSite(creator=user, event_id=event_id, state=state, requested_dt=requested_dt) if static_site.state == StaticSiteState.success: static_site.path = file_path db.session.add(static_site) print cformat( '%{green}+++%{reset} %{white!}{0.event_id:6d}%{reset} ' '%{cyan}{0}%{reset}').format(static_site)
def _handle_legacy_ids(app, **kwargs): """ Handle the redirect from broken legacy event ids such as a12345 or 0123 which cannot be converted to an integer without an error or losing relevant information (0123 and 123 may be different events). """ # Endpoints which need to deal with non-standard event "ids" because they might be shorturls. # Those endpoints handle legacy event ids on their own so we ignore them here. _non_standard_id_endpoints = { 'events.shorturl', 'events.display', 'events.display_overview', 'events.create', 'events.prepare', } # Match event ids which are either not purely numeric or have a leading zero without being exactly `0` _legacy_event_id_re = re.compile(r'/event/((?=0[^/]|\d*[^\d/])[^/]*)') @app.before_request def _redirect_legacy_id(): if request.endpoint in _non_standard_id_endpoints: return if not (match := _legacy_event_id_re.match(request.path)): return event_id = match.group(1) assert is_legacy_id(event_id) if request.method != 'GET': raise BadRequest('Unexpected non-GET request with legacy event ID') mapping = LegacyEventMapping.query.filter_by( legacy_event_id=event_id).first() if mapping is None: raise NotFound(f'Legacy event {event_id} does not exist') new_url = _legacy_event_id_re.sub(f'/event/{mapping.event_id}', request.url, count=1) return redirect(new_url, 302 if app.debug else 301)
def _event_or_shorturl(confId, shorturl_namespace=False, ovw=False): from MaKaC.conference import ConferenceHolder from MaKaC.common.url import ShortURLMapper func = None with DBMgr.getInstance().global_connection(): ch = ConferenceHolder() su = ShortURLMapper() if ch.hasKey(confId): # For obvious reasons an event id always comes first. # If it's used within the short url namespace we redirect to the event namespace, otherwise # we call the RH to display the event if shorturl_namespace: url = UHConferenceDisplay.getURL(ch.getById(confId)) func = lambda: redirect(url) else: params = request.args.to_dict() params['confId'] = confId if ovw: params['ovw'] = 'True' func = lambda: conferenceDisplay.RHConferenceDisplay().process( params) elif (shorturl_namespace or app.config['INDICO_COMPAT_ROUTES']) and su.hasKey(confId): if shorturl_namespace: # Correct namespace => redirect to the event url = UHConferenceDisplay.getURL(su.getById(confId)) func = lambda: redirect(url) else: # Old event namespace => 301-redirect to the new shorturl first to get Google etc. to update it url = url_for('.shorturl', confId=confId) func = lambda: redirect(url, 301) elif is_legacy_id(confId): mapping = LegacyEventMapping.find_first(legacy_event_id=confId) if mapping is not None: url = url_for('event.conferenceDisplay', confId=mapping.event_id) func = lambda: redirect(url, 301) if func is None: raise NotFound( _('The specified event with id or tag "{}" does not exist or has been deleted' ).format(confId)) return func()
def _redirect_legacy_id(): if not request.view_args: return categ_id = request.view_args.get('categId') if categ_id is None or not is_legacy_id(categ_id): return if request.method != 'GET': raise BadRequest( 'Unexpected non-GET request with legacy category ID') mapping = LegacyCategoryMapping.find_first(legacy_category_id=categ_id) if mapping is None: raise NotFound( 'Legacy category {} does not exist'.format(categ_id)) request.view_args['categId'] = unicode(mapping.category_id) return redirect( url_for(request.endpoint, **dict(request.args.to_dict(), **request.view_args)), 301)
def _event_or_shorturl(confId, shorturl_namespace=False, ovw=False): from MaKaC.conference import ConferenceHolder from MaKaC.common.url import ShortURLMapper func = None with DBMgr.getInstance().global_connection(): ch = ConferenceHolder() su = ShortURLMapper() if ch.hasKey(confId): # For obvious reasons an event id always comes first. # If it's used within the short url namespace we redirect to the event namespace, otherwise # we call the RH to display the event if shorturl_namespace: url = UHConferenceDisplay.getURL(ch.getById(confId)) func = lambda: redirect(url) else: params = request.args.to_dict() params['confId'] = confId if ovw: params['ovw'] = 'True' func = lambda: conferenceDisplay.RHConferenceDisplay().process(params) elif (shorturl_namespace or app.config['INDICO_COMPAT_ROUTES']) and su.hasKey(confId): if shorturl_namespace: # Correct namespace => redirect to the event url = UHConferenceDisplay.getURL(su.getById(confId)) func = lambda: redirect(url) else: # Old event namespace => 301-redirect to the new shorturl first to get Google etc. to update it url = url_for('.shorturl', confId=confId) func = lambda: redirect(url, 301) elif is_legacy_id(confId): mapping = LegacyEventMapping.find_first(legacy_event_id=confId) if mapping is not None: url = url_for('event.conferenceDisplay', confId=mapping.event_id) func = lambda: redirect(url, 301) if func is None: raise NotFound(_('The specified event with id or tag "{}" does not exist or has been deleted').format(confId)) return func()
def _redirect_legacy_id(): if not request.view_args or request.endpoint in _non_standard_id_endpoints: return key = event_id = None if "confId" in request.view_args: key = "confId" event_id = request.view_args["confId"] elif "event_id" in request.view_args: key = "event_id" event_id = request.view_args["event_id"] if event_id is None or not is_legacy_id(event_id): return if request.method != "GET": raise BadRequest("Unexpected non-GET request with legacy event ID") mapping = LegacyEventMapping.find_first(legacy_event_id=event_id) if mapping is None: raise NotFound("Legacy event {} does not exist".format(event_id)) request.view_args[key] = unicode(mapping.event_id) return redirect(url_for(request.endpoint, **dict(request.args.to_dict(), **request.view_args)), 301)
def _redirect_legacy_id(): if not request.view_args or request.endpoint in _shorturl_endpoints: return key = event_id = None if 'confId' in request.view_args: key = 'confId' event_id = request.view_args['confId'] elif 'event_id' in request.view_args: key = 'event_id' event_id = request.view_args['event_id'] if event_id is None or not is_legacy_id(event_id): return if request.method != 'GET': raise BadRequest('Unexpected non-GET request with legacy event ID') mapping = LegacyEventMapping.find_first(legacy_event_id=event_id) if mapping is None: raise NotFound('Legacy event {} does not exist'.format(event_id)) request.view_args[key] = unicode(mapping.event_id) return redirect(url_for(request.endpoint, **dict(request.args.to_dict(), **request.view_args)), 301)
def migrate_event_alarms(self): print cformat('%{white!}migrating event alarms/reminders') sent_threshold = now_utc() - timedelta(days=1) for event, alarm in committing_iterator(self._iter_alarms()): if is_legacy_id(event.id): print cformat('%{red!}!!!%{reset} ' '%{white!}{:6s}%{reset} %{yellow!}Event has non-numeric/broken ID').format(event.id) continue elif not alarm.startDateTime: print cformat('%{red!}!!!%{reset} ' '%{white!}{:6s}%{reset} %{yellow!}Alarm has no start time').format(event.id) continue start_dt = self._dt_with_tz(alarm.startDateTime).replace(second=0, microsecond=0) if not hasattr(alarm, 'status'): # Those ancient alarms can be safely assumed to be sent is_sent = True else: is_sent = alarm.status not in {1, 2} # not spooled/queued is_overdue = False if not is_sent and start_dt < sent_threshold: is_sent = True is_overdue = True recipients = filter(None, {convert_to_unicode(x).strip().lower() for x in alarm.toAddr}) reminder = EventReminder(event_id=int(event.id), creator_id=Config.getInstance().getJanitorUserId(), created_dt=alarm.createdOn, scheduled_dt=start_dt, is_sent=is_sent, event_start_delta=getattr(alarm, '_relative', None), recipients=recipients, send_to_participants=alarm.toAllParticipants, include_summary=alarm.confSumary, reply_to_address=convert_to_unicode(alarm.fromAddr).strip().lower(), message=convert_to_unicode(alarm.note).strip()) db.session.add(reminder) status = (cformat('%{red!}OVERDUE%{reset}') if is_overdue else cformat('%{green!}SENT%{reset}') if is_sent else cformat('%{yellow}PENDING%{reset}')) print cformat('%{green}+++%{reset} ' '%{white!}{:6s}%{reset} %{cyan}{}%{reset} {}').format(event.id, reminder.scheduled_dt, status)
def _get_categories(self): # we modify the categories dict so we can't iterate over it while doing so cats = self.flushing_iterator(self.zodb_root['categories'].itervalues()) cats = verbose_iterator(cats, len(self.zodb_root['categories']), attrgetter('id'), attrgetter('name')) return [cat for cat in cats if is_legacy_id(cat.id) or hasattr(cat, '_old_id')]
def _get_events(self): # we modify the conferences dict so we can't iterate over it while doing so events = self.flushing_iterator(self.zodb_root['conferences'].itervalues()) events = verbose_iterator(events, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title')) return [event for event in events if is_legacy_id(event.id) or hasattr(event, '_old_id')]
def _legacy_check(self): if self.ALLOW_LEGACY_IDS: return event_id = request.view_args.get("confId") or request.values.get("confId") if event_id is not None and is_legacy_id(event_id): raise IndicoError("This page is not available for legacy events.")