def convert_support_never(apps, schema_editor): Support = apps.get_model('webplatformcompat', 'Support') has_never = Support.objects.filter(support='never') if has_never.exists(): print('\nConverting support.support="never" to "no"...') Changeset = apps.get_model('webplatformcompat', 'Changeset') HistoricalSupport = apps.get_model( 'webplatformcompat', 'HistoricalSupport') User = apps.get_model(settings.AUTH_USER_MODEL) superuser = User.objects.filter( is_superuser=True).order_by('id').first() assert superuser, 'Must be at least one superuser' cs = Changeset.objects.create(user=superuser) for support in has_never.iterator(): print('Support %d: Converting support to no' % support.id) # Update the instance support.support = 'no' support._delay_cache = True support.save() Cache().delete_all_versions('Support', support.id) # Create a historical support hs = HistoricalSupport( history_date=cs.created, history_changeset=cs, history_type='~', **dict((field.attname, getattr(support, field.attname)) for field in Support._meta.fields)) hs.save() cs.close = True cs.save()
def populate_references(apps, schema_editor, with_create_permissions=True): """Copy data from sections to references.""" Feature = apps.get_model('webplatformcompat', 'Feature') Reference = apps.get_model('webplatformcompat', 'Reference') HistoricalReference = apps.get_model('webplatformcompat', 'HistoricalReference') HistoricalFeature = apps.get_model('webplatformcompat', 'HistoricalFeature') changeset = None cache = Cache() for feature in Feature.objects.all(): if feature.sections.exists(): new_reference_order = [] old_reference_order = feature.get_reference_order() for section in feature.sections.all(): # Trim empty notes note = section.note if note == {'en': ''}: note = None # Add Reference for M2M Feature/Section relationships changed = '' try: reference = Reference.objects.get(feature=feature, section=section) except Reference.DoesNotExist: reference = Reference.objects.create(feature=feature, section=section, note=note) changed = '+' else: if reference.note != note: changed = '~' reference.note = note reference.save() cache.delete_all_versions('Reference', reference.pk) cache.delete_all_versions('Section', section.pk) # Add at least one HistoricalReference entry if changed: changeset = changeset or create_changeset(apps) HistoricalReference.objects.create( history_date=changeset.created, history_changeset=changeset, history_type=changed, **dict( (field.attname, getattr(reference, field.attname)) for field in Reference._meta.fields)) new_reference_order.append(reference.id) # Update Feature.references order if needed if new_reference_order != old_reference_order: feature.set_reference_order(new_reference_order) cache.delete_all_versions('Feature', feature.pk) # Populate null reference lists in historical references HistoricalFeature.objects.filter(references__isnull=True).update( references='[]')
def move_footnotes(apps, schema_editor): Support = apps.get_model("webplatformcompat", "Support") has_footnote = Support.objects.exclude( footnote__isnull=True).exclude(footnote='{}') has_both = has_footnote.exclude(note__isnull=True).exclude(note='{}') if has_both.exists(): raise Exception( "Some supports have both note and footnote set. IDs:", list(has_both.values_list('id', flat=True))) if has_footnote.exists(): print("\nMoving support.footnotes to notes...") Changeset = apps.get_model("webplatformcompat", "Changeset") HistoricalSupport = apps.get_model( "webplatformcompat", "HistoricalSupport") User = apps.get_model(settings.AUTH_USER_MODEL) superuser = User.objects.filter( is_superuser=True).order_by('id').first() assert superuser, "Must be at least one superuser" cs = Changeset.objects.create(user=superuser) for support in has_footnote: print("Support %d: Moving footnote '%s'" % (support.id, repr(support.footnote)[:50])) # Update the instance support.note = support.footnote support.footnote = {} support._delay_cache = True support.save() # Manually clear the cache cache = Cache() if cache.cache: for version in cache.versions: key = cache.key_for(version, "Support", support.id) cache.cache.delete(key) # Create a historical support hs = HistoricalSupport( history_date=cs.created, history_changeset=cs, history_type="~", **dict((field.attname, getattr(support, field.attname)) for field in Support._meta.fields)) hs.save() cs.close = True cs.save()
def populate_sections(apps, schema_editor): """Copy data from references back to sections.""" Feature = apps.get_model('webplatformcompat', 'Feature') Reference = apps.get_model('webplatformcompat', 'Reference') Section = apps.get_model('webplatformcompat', 'Section') HistoricalSection = apps.get_model('webplatformcompat', 'HistoricalSection') HistoricalFeature = apps.get_model('webplatformcompat', 'HistoricalFeature') changeset = None cache = Cache() for feature in Feature.objects.all(): if feature.references.exists(): reference_order = feature.get_reference_order() old_section_order = feature.sections.values_list('id', flat=True) new_section_order = [] # Add M2M Feature/Section relationship for each Reference for reference_id in reference_order: reference = Reference.objects.get(id=reference_id) section = reference.section if section.note != reference.note: section.note = reference.note section.save() cache.delete_all_versions('Section', section.pk) changeset = changeset or create_changeset(apps) HistoricalSection.objects.create( history_date=changeset.created, history_changeset=changeset, history_type='~', **dict((field.attname, getattr(section, field.attname)) for field in Section._meta.fields)) new_section_order.append(section.id) # Update Feature.sections order if needed if new_section_order != old_section_order: feature.sections = new_section_order cache.delete_all_versions('Feature', feature.pk) # Return empty Feature.resources lists to null HistoricalFeature.objects.filter(references='[]').update(references=None)
def convert_empty_versions(apps, schema_editor): Version = apps.get_model('webplatformcompat', 'Version') # Database stores as empty string, API converts to null has_blank = Version.objects.filter(version='') has_bad_status = has_blank.exclude(status__in=('current', 'unknown')) if has_bad_status.exists(): raise Exception( 'Some versions with empty version strings have an unexpected' ' status. IDs:', list(has_bad_status.values_list('id', flat=True))) if has_blank.exists(): print('\nConverting blank version.version to "current"...') Changeset = apps.get_model('webplatformcompat', 'Changeset') HistoricalVersion = apps.get_model('webplatformcompat', 'HistoricalVersion') User = apps.get_model(settings.AUTH_USER_MODEL) superuser = User.objects.filter( is_superuser=True).order_by('id').first() assert superuser, 'Must be at least one superuser' cs = Changeset.objects.create(user=superuser) for version in has_blank: print('Version %d: Converting version to "current"' % version.id) # Update the instance version.version = 'current' version.status = 'current' version._delay_cache = True version.save() Cache().delete_all_versions('Version', version.id) # Create a historical version hs = HistoricalVersion(history_date=cs.created, history_changeset=cs, history_type='~', **dict((field.attname, getattr(version, field.attname)) for field in Version._meta.fields)) hs.save() cs.close = True cs.save()
def test_large_feature_tree_cached_feature(self): feature = self.setup_feature_tree() cached_qs = CachedQueryset(Cache(), Feature.objects.all(), primary_keys=[feature.pk]) cached_feature = cached_qs.get(pk=feature.pk) self.assertEqual(cached_feature.pk, feature.id) self.assertEqual(cached_feature.descendant_count, 3) self.assertEqual(cached_feature.descendant_pks, []) # Too big to cache url = self.api_reverse('viewfeatures-detail', pk=cached_feature.pk) context = self.make_context(url, include_child_pages=True) serializer = ViewFeatureSerializer(context=context) representation = serializer.to_representation(cached_feature) next_page = url + '?child_pages=1&page=2' expected_pagination = { 'linked.features': { 'previous': None, 'next': self.baseUrl + next_page, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertDataEqual(expected_pagination, actual_pagination) context2 = self.make_context(next_page, include_child_pages=True) serializer2 = ViewFeatureSerializer(context=context2) representation = serializer2.to_representation(feature) expected_pagination = { 'linked.features': { 'previous': self.baseUrl + url + '?child_pages=1&page=1', 'next': None, 'count': 3, } } compat_table = representation['_view_extra']['meta']['compat_table'] actual_pagination = compat_table['pagination'] self.assertEqual(expected_pagination, actual_pagination)
def setUp(self): self.cache = Cache() self.login_user(groups=['change-resource'])