유일한 문제는 스크립트가 선택하는 사용자 이름에 만족하지 못할 때입니다. 따라서 다음과 같은 일이 일어나는 것에 신경 쓰지 않는다면:
clan|nickname→ clan_nickname[clan]nickname→ clan_nickname2
대부분의 경우 문제없을 것입니다. 또한 같은 클랜에서 동일한 닉네임이지만 추가 문자가 다른 두 사용자가 있을 가능성은 매우 낮으므로, 아마도 괜찮을 것입니다.
유일한 문제는 스크립트가 선택하는 사용자 이름에 만족하지 못할 때입니다. 따라서 다음과 같은 일이 일어나는 것에 신경 쓰지 않는다면:
clan|nickname → clan_nickname[clan]nickname → clan_nickname2대부분의 경우 문제없을 것입니다. 또한 같은 클랜에서 동일한 닉네임이지만 추가 문자가 다른 두 사용자가 있을 가능성은 매우 낮으므로, 아마도 괜찮을 것입니다.
불행히도 우리는 마이그레이션 스크립트를 전적으로 직접 작성해야 했습니다. 당시(2022년 말) 이용 가능한 스크립트는 분명히 ‘완성’ 상태가 아니었습니다. 참조된 코드 조각이 누락된 부분이 있었고, 다른 부분은 전혀 의미가 없었습니다.
처리해야 했던 부분 중 하나는 Discourse 표준을 준수하지 않는 사용자 이름의 변경이었습니다. 사용자가 1만 명을 초과했기 때문에, 우리는 사용자 이름을 이러한 제한이 없는 “user name” 필드에 단순히 할당했습니다. 그리고 규칙을 위반하는 사용자 이름은 해당 사용자 이름의 md5 문자열로 변경했습니다. 이후 사용자에게 1개월의 기간을 주어 자유롭게 사용자 이름을 변경할 수 있도록 하여, 원래 이름과 유사한 것으로 되돌릴 수 있게 했습니다.
다음은 코드 일부입니다:
public static string ParseName(string text)
{
var reservedName = new string[] { "user", "system", "moderators" };
var result = NormalizeText(text);
// If reserved change it
if (reservedName.Contains(result, StringComparer.OrdinalIgnoreCase))
result = text.ToLower().ToMD5();
// Invalid alphanumeric
else if (!Regex.IsMatch(result, @"^[a-zA-Z0-9_.-]*$"))
result = text.ToLower().ToMD5();
// Invalid repeated
else if (Regex.IsMatch(result, @"[-_.]{2,}"))
result = text.ToLower().ToMD5();
// Invalid trailing char
else if (Regex.IsMatch(result, @"/[\p{L}\p{N}]+$/"))
result = text.ToLower().ToMD5();
// Confusing extensions
else if (Regex.IsMatch(result, @"/\.(js|json|css|htm|html|xml|jpg|jpeg|png|gif|bmp|ico|tif|tiff|woff)$/i"))
result = text.ToLower().ToMD5();
// Starting and ending dots
else if (result.StartsWith(".") || result.EndsWith("."))
result = text.ToLower().ToMD5();
// No more than 60 character
result = result.Truncate(60);
return result;
}
제한 사항으로 간주될 내용을 결정하기 위해 이 파일을 참조했습니다. 그사이 변경되었을 수 있으므로 주의를 기울이시기 바랍니다.
기존의 가져오기(import) 스크립트를 기반으로 하셨나요? 그랬다면 https://github.com/discourse/discourse/blob/main/lib/user_name_suggester.rb를 호출했을 것이고, 그냥 작동했을 겁니다.
아니요, 1,000만 개 이상의 게시글을 처리할 때 스크립트가 incredibly 느렸기 때문에 스크립트를 사용하지 않았습니다.
우리는 C#으로 모든 것을 처음부터 만들었습니다. 아바타를 제외한 모든 것을 마이그레이션하고 서로 다른 URL 형식에 맞춰 리디렉트를 생성하는 데 약 4~5시간이 걸렸습니다. 스크립트를 특정 매개변수와 함께 두 번째로 실행하면 지난 6개월 동안 활동한 각 사용자의 아바타도 업데이트하고, 게시글을 스캔하여 기존 URL 형식을 찾아 필요한 모든 리디렉트를 추가할 수 있습니다.
이 과정은 대략 며칠 정도 걸렸지만, 우리에게는 포럼의 모든 콘텐츠가 하루 안에 정상적으로 운영되는 것이 가장 중요했기 때문에 백그라운드에서 진행할 수 있는 작업이었습니다.
잘했어요! 정말 멋집니다.
참고로, 기존 스크립트는 이미 존재하는 콘텐츠를 건너뛰기 때문에, 최종 가져오기에는 1시간 미만만 걸렸을 가능성이 높습니다. 특히 가장 최근에 가져온 데이터의 날짜를 지정해 주었다면 더욱 그렇습니다. 다만, 첫 실행은 매우 고통스러웠을 것입니다.
네, 재개된 건 알고 있어요. 근데 예전 콘텐츠가 너무 엉망이었거든요 (포럼이 2000년 초에 마이그레이션을 한 적이 있어요). 그래서 스크립트가 대부분 실패하거나 금방 기어처럼 느려지는 문제가 있었어요.
믿어주세요, 3개월간의 작성과 테스트를 피할 수 있었다면 당연히 피했을 거예요! ![]()