def migrate_legacy_categories(self): print cformat('%{white!}migrating legacy categories') indexes = [ self.zodb_root['categories'], self.zodb_root['catalog']['categ_conf_sd']._container ] indexes += [ self.zodb_root['indexes'][x]._idxCategItem for x in ('category', 'categoryDate', 'categoryDateAll') ] mapping = {} for categ in self._committing_iterator(self._get_categories()): if not hasattr(categ, '_old_id'): new_id = self.gen_categ_id() index_data = [idx.pop(categ.id, None) for idx in indexes] categ._old_id = categ.id categ.id = new_id for idx, data in zip(indexes, index_data): assert categ.id not in idx if data is not None: idx[categ.id] = data self.zodb_root['categories'][categ.id] = categ IndexedCategory.find(id=categ._old_id).update( {IndexedCategory.id: categ.id}) FavoriteCategory.find(target_id=categ._old_id).update( {FavoriteCategory.target_id: categ.id}) db.session.add( LegacyCategoryMapping(legacy_category_id=categ._old_id, category_id=int(categ.id))) print cformat('%{green}+++%{reset} ' '%{white!}{:6s}%{reset} %{cyan}{}').format( categ._old_id, int(categ.id)) else: # happens if this importer was executed before but you want to add the mapping to your DB again db.session.add( LegacyCategoryMapping(legacy_category_id=categ._old_id, category_id=int(categ.id))) msg = cformat( '%{green}+++%{reset} ' '%{white!}{:6s}%{reset} %{cyan}{}%{reset} %{yellow}(already updated in zodb)' ) print msg.format(categ._old_id, int(categ.id)) mapping[categ._old_id] = categ.id print cformat('%{white!}fixing subcategory lists') for categ in self._committing_iterator( self.flushing_iterator( self.zodb_root['categories'].itervalues())): for subcateg_id in categ.subcategories.keys(): new_id = mapping.get(subcateg_id) if new_id is not None: categ.subcategories[new_id] = categ.subcategories.pop( subcateg_id) categ._p_changed = True
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 export_categ(self, user): expInt = CategoryEventFetcher(user, self) id_list = set(self._idList) if self._wantFavorites and user: id_list.update(str(c.id) for c in user.favorite_categories) legacy_id_map = {m.legacy_category_id: m.category_id for m in LegacyCategoryMapping.find(LegacyCategoryMapping.legacy_category_id.in_(id_list))} id_list = {str(legacy_id_map.get(id_, id_)) for id_ in id_list} return expInt.category(id_list, self._format)
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 compat_category(legacy_category_id, path=None): if not re.match(r'^\d+l\d+$', legacy_category_id): abort(404) mapping = LegacyCategoryMapping.find_first( legacy_category_id=legacy_category_id) if mapping is None: raise NotFound(f'Legacy category {legacy_category_id} does not exist') view_args = request.view_args.copy() view_args['legacy_category_id'] = mapping.category_id # To create the same URL with the proper ID we take advantage of the # fact that the legacy endpoint works perfectly fine with proper IDs # too (you can pass an int for a string argument), but due to the # weight of the `int` converter used for new endpoints, the URL will # then be handled by the proper endpoint instead of this one. return redirect( url_for(request.endpoint, **dict(request.args.to_dict(), **view_args)), 301)
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 _category_deleted(category, **kwargs): if hasattr(category, '_old_id'): LegacyCategoryMapping.find( legacy_category_id=category._old_id).delete()
def _category_deleted(category, **kwargs): if hasattr(category, '_old_id'): LegacyCategoryMapping.find(legacy_category_id=category._old_id).delete()