Added a data migration to fix recent slides names containing underscores.
- Legacy-Id: 13997
This commit is contained in:
parent
0fc216b7fd
commit
6eda346356
201
ietf/meeting/migrations/0056_fix-slide-name-slugs.py
Normal file
201
ietf/meeting/migrations/0056_fix-slide-name-slugs.py
Normal file
|
@ -0,0 +1,201 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2017-07-23 08:27
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
import os
|
||||
import copy
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
def get_materials_path(meeting):
|
||||
return os.path.join(settings.AGENDA_PATH,meeting.number)
|
||||
|
||||
def get_file_path(self):
|
||||
if not hasattr(self, '_cached_file_path'):
|
||||
if self.type_id == "draft":
|
||||
if self.is_dochistory():
|
||||
self._cached_file_path = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR
|
||||
else:
|
||||
if self.get_state_slug() == "rfc":
|
||||
self._cached_file_path = settings.RFC_PATH
|
||||
else:
|
||||
draft_state = self.get_state('draft')
|
||||
if draft_state and draft_state.slug == 'active':
|
||||
self._cached_file_path = settings.INTERNET_DRAFT_PATH
|
||||
else:
|
||||
self._cached_file_path = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR
|
||||
elif self.type_id in ("agenda", "minutes", "slides", "bluesheets"):
|
||||
doc = self.doc if isinstance(self, DocHistory) else self
|
||||
if doc.session_set.exists():
|
||||
meeting = doc.session_set.first().meeting
|
||||
self._cached_file_path = os.path.join(get_materials_path(meeting), self.type_id) + "/"
|
||||
else:
|
||||
self._cached_file_path = ""
|
||||
elif self.type_id == "charter":
|
||||
self._cached_file_path = settings.CHARTER_PATH
|
||||
elif self.type_id == "conflrev":
|
||||
self._cached_file_path = settings.CONFLICT_REVIEW_PATH
|
||||
elif self.type_id == "statchg":
|
||||
self._cached_file_path = settings.STATUS_CHANGE_PATH
|
||||
else:
|
||||
self._cached_file_path = settings.DOCUMENT_PATH_PATTERN.format(doc=self)
|
||||
return self._cached_file_path
|
||||
|
||||
def get_base_name(self):
|
||||
if not hasattr(self, '_cached_base_name'):
|
||||
if self.type_id == 'draft':
|
||||
if self.is_dochistory():
|
||||
self._cached_base_name = "%s-%s.txt" % (self.doc.name, self.rev)
|
||||
else:
|
||||
if self.get_state_slug() == 'rfc':
|
||||
self._cached_base_name = "%s.txt" % self.canonical_name()
|
||||
else:
|
||||
self._cached_base_name = "%s-%s.txt" % (self.name, self.rev)
|
||||
elif self.type_id in ["slides", "agenda", "minutes", "bluesheets", ]:
|
||||
if self.external_url:
|
||||
# we need to remove the extension for the globbing below to work
|
||||
self._cached_base_name = self.external_url
|
||||
else:
|
||||
self._cached_base_name = "%s.txt" % self.canonical_name() # meeting materials are unversioned at the moment
|
||||
elif self.type_id == 'review':
|
||||
self._cached_base_name = "%s.txt" % self.name
|
||||
else:
|
||||
if self.rev:
|
||||
self._cached_base_name = "%s-%s.txt" % (self.canonical_name(), self.rev)
|
||||
else:
|
||||
self._cached_base_name = "%s.txt" % (self.canonical_name(), )
|
||||
return self._cached_base_name
|
||||
|
||||
|
||||
def get_file_name(self):
|
||||
if not hasattr(self, '_cached_file_name'):
|
||||
self._cached_file_name = os.path.join(self.get_file_path(), self.get_base_name())
|
||||
return self._cached_file_name
|
||||
|
||||
def get_state_slug(self, state_type=None):
|
||||
"""Get state of type, or default if not specified, returning
|
||||
the slug of the state or None. This frees the caller of having
|
||||
to check against None before accessing the slug for a
|
||||
comparison."""
|
||||
s = self.get_state(state_type)
|
||||
if s:
|
||||
return s.slug
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_state(self, state_type=None):
|
||||
"""Get state of type, or default state for document type if
|
||||
not specified. Uses a local cache to speed multiple state
|
||||
reads up."""
|
||||
if self.pk == None: # states is many-to-many so not in database implies no state
|
||||
return None
|
||||
|
||||
if state_type == None:
|
||||
state_type = self.type_id
|
||||
|
||||
if not hasattr(self, "state_cache") or self.state_cache == None:
|
||||
self.state_cache = {}
|
||||
for s in self.states.all():
|
||||
self.state_cache[s.type_id] = s
|
||||
|
||||
return self.state_cache.get(state_type, None)
|
||||
|
||||
def canonical_name(self):
|
||||
if not hasattr(self, '_canonical_name'):
|
||||
name = self.name
|
||||
if self.type_id == "draft" and self.get_state_slug() == "rfc":
|
||||
a = self.docalias_set.filter(name__startswith="rfc").first()
|
||||
if a:
|
||||
name = a.name
|
||||
elif self.type_id == "charter":
|
||||
from ietf.doc.utils_charter import charter_name_for_group # Imported locally to avoid circular imports
|
||||
try:
|
||||
name = charter_name_for_group(self.chartered_group)
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
self._canonical_name = name
|
||||
return self._canonical_name
|
||||
|
||||
def move_related_objects(source, target, file, verbose=False):
|
||||
'''Find all related objects and migrate'''
|
||||
related_objects = [ f for f in source._meta.get_fields()
|
||||
if (f.one_to_many or f.one_to_one)
|
||||
and f.auto_created and not f.concrete ]
|
||||
for related_object in related_objects:
|
||||
accessor = related_object.get_accessor_name()
|
||||
field_name = related_object.field.name
|
||||
try:
|
||||
queryset = getattr(source, accessor).all()
|
||||
if verbose:
|
||||
print("Merging {}:{}".format(accessor,queryset.count()),file=file)
|
||||
kwargs = { field_name:target }
|
||||
queryset.update(**kwargs)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
def fix_exturl(d):
|
||||
filename = d.get_file_name()
|
||||
new = filename.replace('_', '-')
|
||||
if os.path.exists(filename):
|
||||
os.rename(filename, new)
|
||||
elif not os.path.exists(new):
|
||||
print(" ** Neither old (%s) or new (%s) filename found" % (filename, new))
|
||||
d.external_url = d.external_url.replace('_', '-')
|
||||
|
||||
def forwards(apps, schema_editor):
|
||||
global Document, DocHistory, DocAlias
|
||||
Document = apps.get_model('doc', 'Document')
|
||||
DocHistory = apps.get_model('doc', 'DocHistory')
|
||||
DocAlias = apps.get_model('doc', 'DocAlias')
|
||||
#
|
||||
Document.get_file_name = get_file_name
|
||||
Document.get_base_name = get_base_name
|
||||
Document.get_file_path = get_file_path
|
||||
Document.get_state_slug = get_state_slug
|
||||
Document.get_state = get_state
|
||||
Document.canonical_name = canonical_name
|
||||
#
|
||||
DocHistory.get_file_name = get_file_name
|
||||
DocHistory.get_base_name = get_base_name
|
||||
DocHistory.get_file_path = get_file_path
|
||||
DocHistory.get_state_slug = get_state_slug
|
||||
DocHistory.get_state = get_state
|
||||
DocHistory.canonical_name = canonical_name
|
||||
|
||||
|
||||
print("")
|
||||
for doc in Document.objects.filter(name__contains='_').filter(name__startswith='slides'):
|
||||
for hdoc in DocHistory.objects.filter(name=doc.name):
|
||||
hdoc.name = hdoc.name.replace('_', '-')
|
||||
fix_exturl(hdoc)
|
||||
hdoc.save()
|
||||
old_doc = copy.deepcopy(doc)
|
||||
doc.name = doc.name.replace('_', '-')
|
||||
fix_exturl(doc)
|
||||
doc.save()
|
||||
for old_alias in old_doc.docalias_set.all():
|
||||
aname = old_alias.name.replace('_', '-')
|
||||
print("New alias %s" % aname)
|
||||
alias = DocAlias.objects.create(name=aname, document=doc)
|
||||
move_related_objects(old_alias, alias, sys.stdout, verbose=True)
|
||||
old_alias.delete()
|
||||
move_related_objects(old_doc, doc, sys.stdout, verbose=False)
|
||||
old_doc.delete()
|
||||
|
||||
def backwards(apps, schema_editor):
|
||||
pass
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('meeting', '0055_old_id_cutoffs'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(forwards, backwards),
|
||||
]
|
Loading…
Reference in a new issue