Migrate a phpBB3 forum to Discourse

마크다운도 잘 동작해야 하지만, <strong>을 사용하는 것이 더 많은 엣지 케이스를 우회할 수 있을 것 같습니다. 다만, HTML과 마크다운을 혼합하는 것에도 몇 가지 주의할 점이 있습니다… 간단한 마크다운 해결책은 다음과 같습니다:

**multiline\
\
text**

어떤 버전의 phpBB에서 가져오는 건지 궁금합니다. 3.2 버전에서는 이전 버전보다 BBCode를 마크다운으로 변환하는 과정이 훨씬 잘 되어 있습니다. 이상적으로는 가져온 게시물에서 더 이상 [b]를 보지 않아야 합니다.

2개의 좋아요

말씀이 맞으신 것 같은데, 왜 처음에 그걸 생각하지 못했을까요…

phpBB 3.0.7-PL1에서 이식하고 있습니다.

2개의 좋아요

가져오기 전에 3.2로 업그레이드하면 큰 도움이 될 것입니다. :wink:

모든 게시물의 BBCode가 새로운 저장 형식으로 마이그레이션되었는지 확인하려면 phpBB 리파서를 실행하십시오: https://www.phpbb.com/support/docs/en/3.3/kb/article/phpbb-32%2B-text-reparser/

3개의 좋아요

처음에는 그렇게 생각했는데… 저는 컴퓨터 관련 일을 정말 싫어하거든요. :sweat_smile:
phpBB에 대해 잘 모르고, 이렇게 오래된 버전에서 업데이트할 때 발생할 수 있는 오류를 처리하고 싶지 않았어요.

Discourse 마이그레이션 스크립트가 phpBB 3.0과 호환되므로, phpBB를 업그레이드하지 않기로 결정했습니다…
phpBB를 업그레이드했다면 제가 겪은 일부 bbcode 문제를 피할 수 있었을지도 몰라요. 중첩 목록, 줄바꿈이 포함된 [b] 태그 같은 것들이요…:man_shrugging:

하지만 12월부터 가져오기 작업을 시작해서 이제 잘 작동하는 가져오기를 거의 완성할 단계(이상적으로는 새 포럼이 아마 두 주 안에 온라인으로 열릴 예정…)에 이르렀고, phpBB 3.2 가져오기 도구가 이러한 문제를 더 잘 처리하는지 확인하기 위해 제가 만든 모든 커스텀 가져오기 수정 사항을 다시 검토해야 할 수도 있는 phpBB 업그레이드를 지금 실험하고 싶지는 않아요 :sweat_smile:. 시간이 많이 걸릴 테니까요.

그럼에도 불구하고… 이번 주말 오후에 충분히 지루하다면 뭔가 실험해 볼 수도 있겠네요!


수정: 시도해 봤는데, 새 서버로 이전한 후 phpBB 3.2로 업그레이드하는 것은 고역입니다. HTTPS 문제, 캐시 문제, 기타 문제들. 우회적이고 답답한 절차들. 공식 튜토리얼은 오래된 PHP 버전을 요구하는 도구를 사용하라고 조언하네요 (아, PHP 5, 오랜만이군요…). 분명히 가끔은 지루하지만, 미친 건 아니에요 - 적어도 이런 종류의 일을 할 정도로는요.

Gerhard! 당신을 오도하고 있어요! 3.2로 업그레이드하는 것은 큰 도움이 아니에요! :laughing:

하지만 phpBB 자체에 대해 더 이상 이야기하지 마세요… 그리고 Discourse의 원클릭 업그레이드에 감사드리죠.

1개의 좋아요

안녕하세요,

WordPress 사용자를 Discourse로 이식하는 작업을 진행 중입니다. Docker 컨테이너에서 WP 데이터베이스에 연결하고 사용자를 가져오는 과정을 지침에 따라 완료했습니다. SSO WordPress 플러그인을 사용 중이므로, 이식 중 또는 이식 후 이메일이 발송되지 않도록 확인하고 싶습니다.

이식 완료 후 백그라운드 작업으로 이메일 확인이 발송될 경우를 대비하여 이메일 앞에 “import_” 접두사를 붙였습니다.

이식 후 last_emailed_at 컬럼이 설정된 것을 확인했습니다:

이는 ImportScripts::Base::create_user() 내에서 opts[:last_emailed_at] = opts.fetch(:last_emailed_at, Time.now)에 의해 설정된다는 것을 알고 있습니다.

ImportScripts::Base::create_admin에서 이메일을 확인하는 데 사용되는 admin.email_tokens.update_all(confirmed: true)와 유사한 기능이 있을까요?

이메일이 발송되었다는 로그를 찾지 못했습니다. 실제로 이메일이 발송되었나요? 이메일을 유효한 것으로 변경한 후에도 Discourse가 이메일을 발송하려고 할까요?

1개의 좋아요

이 주제는 phpBB3 마이그레이션에 관한 것이므로, 이 내용은 오프토픽입니다… :wink:

일부 사용자가 절대 이메일을 받지 못하도록 확실하게 하고 싶다면 .invalid 도메인을 사용하는 것을 권장합니다 (예: foo@mywpimport.invalid). 하지만 단순히 준비가 될 때까지 발신 이메일을 비활성화하려는 것이라면, disable_emails 사이트 설정을 “yes” 또는 "non-staff"로 설정하는 것이 가장 좋은 방법입니다!

발신 이메일은 가져오기(import) _중간_에 자동으로 비활성화됩니다. last_emailed_at 속성의 값들은 아마도 Discourse가 이메일을 보내려 _시도_하다가, 이를 허용할 수 없다는 사실을 발견하기 전에 발생한 것일 것입니다.

Discourse는 마이그레이션 _이후_에도 이메일을 보내려고 시도할 것입니다.

2개의 좋아요

감사합니다. 처음에는 이메일 필드에 빈 문자열을 시도해 보았지만, ImportScript 기반 클래스가 잘못된 도메인을 가진 가짜 이메일을 생성했습니다. 또한 last_emailed_at 속성도 설정되어 있었습니다.

즉, 데이터베이스에서 이메일을 수정하는 즉시 Discourse가 이메일 전송을 시도한다는 말씀이신가요? 하지만 WordPress로 인증된 일반 로그인에는 이메일 확인이 필요하지 않습니다. ImportScript를 사용하여 이 문제를 우회할 방법이 없나요?

1개의 좋아요

마이그레이션은 완료되었고 성공적이었습니다.
하지만 두 가지 문제가 있습니다. 오프토픽이라면 알려주세요.

  1. 일부 게시글 내용에 다음과 같은 형식의 콘텐츠가 있습니다:

    [url=https://www.casimages.com/i/1907271141431956116331631.jpg.html][ 
    [img]https://nsm09.casimages.com/img/2019/07/27//1907271141431956116331631.jpg[/img][/url]
    

    이미지 미리보기에는 표시되지만, HTML을 다시 빌드해도 게시글 본문에서는 깨져 보입니다:

    각 이미지에 대해 생성된 HTML은 다음과 같습니다:

    <p><a href="https://www.casimages.com/i/1907271151181956116331666.jpg.html" data-bbcode="true"><span alt="" class="broken-image" title="This image is broken"><svg class="fa d-icon d-icon-unlink svg-icon" aria-hidden="true"><use href="#unlink"></use></svg></span></a></p>
    

    많은 게시글에서 이 문제를 겪고 있습니다. 전역적으로 수정할 수 있는 아이디어가 있으신가요?

  2. 많은 오래된 포럼처럼, 오래된 Imageshack 링크는 이미 오래전에 깨졌고 앞으로도 깨진 채로 남을 것입니다. 하지만 일부 링크는 아무것도 표시되지 않는 대신 우크라이나 국기가 표시됩니다:

    이 동작은 어떻게 처리하시겠습니까?
    어떤 아이디어도 환영합니다. 다만, 포럼 관리자가 오래된 하드 드라이브에 포럼 전체의 정적 저장본을 가지고 있으며, 그곳에는 대부분의 오래된 이미지가 유효합니다(다운로드하여 로컬에 저장되어 있음). 미래에 스크립트를 작성하여 Imageshack의 “죽은” 링크를 정적 버전의 유효한 이미지로 대체할 수 있을 것 같습니다. 매우 까다로운 작업으로 보이지만, 이 때문에 포럼에서 모든 Imageshack 링크를 빈 문자열 등으로 대체하여 단순히 제거하는 것은 원하지 않습니다.

1개의 좋아요

줄바꿈이 문제를 일으키는 건가요? 제 추측으로는 그렇습니다. 줄바꿈을 제거하려면 해당 BBCode를 재매핑해야 합니다. Replace a string in all posts 가 도움이 될 것입니다.

일단 HTML 주석으로 변환해 보는 건 어떨까요? 나중에 저장된 이미지로 대체할 수 있습니다.

2개의 좋아요

그것이 문제인 것 같지는 않습니다:
내용이 다음과 같이 보이도록 줄바꿈을 추가했습니다:

[url=https://www.casimages.com/i/1907271141431956116331631.jpg.html]

[img]https://nsm09.casimages.com/img/2019/07/27//1907271141431956116331631.jpg[/img]

[/url]

그리고 결과는 다음과 같습니다:

예시 게시물:

네, 좋은 아이디어입니다! :+1: 즉, 정칙 표현식을 사용하여 Imageshack 링크만 표적으로 삼아 문자열(링크하신 주제에서 가져온 것)을 대체하는 것이 맞나요?

2개의 좋아요

새로운 줄을 실험해 본 결과, 이것이 문제가 아니었습니다.

하지만 게시물 내용을 같은 포럼의 새 게시물에 복사-붙여넣기하면 내용이 올바르게 표시됩니다 :woozy_face: :question: :


(그리고 핫링크된 이미지들도 성공적으로 로컬로 다운로드됩니다)

반면:

이미지가 깨진 게시물을 재베이킹(rebaking)해 보았지만(메시지 미리보기에서는 올바르게 표시됨, 이전 게시물 참고) 아무것도 해결되지 않았습니다.

제가 아는 한, 두 게시물의 원본(raw) 내용은 정확히 동일합니다.

하지만 첫 번째 게시물(두 번째 줄)의 쿠크드(cooked) 콘텐츠는 이미지가 깨진 결과를 초래합니다:

아주 당황스럽습니다.

1개의 좋아요

이상한 일이 하나 있습니다:
어떤 게시글의 HTML을 다시 빌드하려고 하면 500 오류가 발생합니다:

로그에는 치명적 오류(fatal error)와 경고(warning)가 표시됩니다:

로그 창 스크린샷:

치명적 오류:

ArgumentError (wrong number of arguments (given 0, expected 1)) lib/guardian/ensure_magic.rb:11:in 'method_missing' app/controllers/posts_controller.rb:570:in 'rebake' app/controllers/application_cont

plugins/discourse-chat/lib/guardian_extensions.rb:71:in `can_rebake?'
lib/guardian/ensure_magic.rb:11:in `method_missing'
app/controllers/posts_controller.rb:570:in `rebake'
actionpack (6.1.4.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.1.4.1) lib/abstract_controller/base.rb:228:in `process_action'
actionpack (6.1.4.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.1.4.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.1.4.1) lib/active_support/callbacks.rb:117:in `block in run_callbacks'
app/controllers/application_controller.rb:397:in `block in with_resolved_locale'
i18n (1.10.0) lib/i18n.rb:328:in `with_locale'
app/controllers/application_controller.rb:397:in `with_resolved_locale'
activesupport (6.1.4.1) lib/active_support/callbacks.rb:126:in `block in run_callbacks'
activesupport (6.1.4.1) lib/active_support/callbacks.rb:137:in `run_callbacks'
actionpack (6.1.4.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.1.4.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.1.4.1) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
activesupport (6.1.4.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.4.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.4.1) lib/active_support/notifications.rb:203:in `instrument'
actionpack (6.1.4.1) lib/action_controller/metal/instrumentation.rb:33:in `process_action'
actionpack (6.1.4.1) lib/action_controller/metal/params_wrapper.rb:249:in `process_action'
activerecord (6.1.4.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.1.4.1) lib/abstract_controller/base.rb:165:in `process'
actionview (6.1.4.1) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (3.0.0) lib/mini_profiler/profiling_methods.rb:85:in `block in profile_method'
actionpack (6.1.4.1) lib/action_controller/metal.rb:190:in `dispatch'
actionpack (6.1.4.1) lib/action_controller/metal.rb:254:in `dispatch'
actionpack (6.1.4.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack (6.1.4.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.1.4.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (6.1.4.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.1.4.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.1.4.1) lib/action_dispatch/routing/route_set.rb:842:in `call'
lib/middleware/omniauth_bypass_middleware.rb:71:in `call'
rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.3) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.3) lib/rack/head.rb:12:in `call'
actionpack (6.1.4.1) lib/action_dispatch/http/permissions_policy.rb:22:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:358:in `call'
rack (2.2.3) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.3) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/cookies.rb:689:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.1.4.1) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (6.1.4.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
logster (2.10.1) lib/logster/middleware/reporter.rb:43:in `call'
railties (6.1.4.1) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.1.4.1) lib/rails/rack/logger.rb:28:in `call'
config/initializers/100-quiet_logger.rb:23:in `call'
config/initializers/100-silence_logger.rb:31:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/request_id.rb:26:in `call'
lib/middleware/enforce_hostname.rb:23:in `call'
rack (2.2.3) lib/rack/method_override.rb:24:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
actionpack (6.1.4.1) lib/action_dispatch/middleware/host_authorization.rb:92:in `call'
rack-mini-profiler (3.0.0) lib/mini_profiler/profiler.rb:249:in `call'
message_bus (4.2.0) lib/message_bus/rack/middleware.rb:60:in `call'
lib/middleware/request_tracker.rb:202:in `call'
railties (6.1.4.1) lib/rails/engine.rb:539:in `call'
railties (6.1.4.1) lib/rails/railtie.rb:207:in `public_send'
railties (6.1.4.1) lib/rails/railtie.rb:207:in `method_missing'
rack (2.2.3) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.3) lib/rack/urlmap.rb:58:in `each'
rack (2.2.3) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
vendor/bundle/ruby/2.7.0/bin/unicorn:25:in `load'
vendor/bundle/ruby/2.7.0/bin/unicorn:25:in `<main>'

모든 테마와 플러그인이 비활성화된 안전 모드(safe-mode)에서 실행되었지만, 이 코드 블록의 첫 번째 줄에서 언급된 내용은 다음과 같습니다:
plugins/discourse-chat/lib/guardian_extensions.rb:71:in 'can_rebake?'

경고:

Failed to handle exception in exception app middleware : ArgumentError : wrong number of arguments (given 0, expected 1)

/var/www/discourse/plugins/discourse-chat/lib/guardian_extensions.rb:71:in `can_rebake?'
/var/www/discourse/lib/guardian/ensure_magic.rb:11:in `method_missing'
/var/www/discourse/app/controllers/posts_controller.rb:570:in `rebake'
actionpack-6.1.4.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack-6.1.4.1/lib/abstract_controller/base.rb:228:in `process_action'
actionpack-6.1.4.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack-6.1.4.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport-6.1.4.1/lib/active_support/callbacks.rb:117:in `block in run_callbacks'
/var/www/discourse/app/controllers/application_controller.rb:397:in `block in with_resolved_locale'
i18n-1.10.0/lib/i18n.rb:328:in `with_locale'
/var/www/discourse/app/controllers/application_controller.rb:397:in `with_resolved_locale'
activesupport-6.1.4.1/lib/active_support/callbacks.rb:126:in `block in run_callbacks'
activesupport-6.1.4.1/lib/active_support/callbacks.rb:137:in `run_callbacks'
actionpack-6.1.4.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack-6.1.4.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack-6.1.4.1/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
activesupport-6.1.4.1/lib/active_support/notifications.rb:203:in `block in instrument'
activesupport-6.1.4.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport-6.1.4.1/lib/active_support/notifications.rb:203:in `instrument'
actionpack-6.1.4.1/lib/action_controller/metal/instrumentation.rb:33:in `process_action'
actionpack-6.1.4.1/lib/action_controller/metal/params_wrapper.rb:249:in `process_action'
activerecord-6.1.4.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack-6.1.4.1/lib/abstract_controller/base.rb:165:in `process'
actionview-6.1.4.1/lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler-3.0.0/lib/mini_profiler/profiling_methods.rb:85:in `block in profile_method'
actionpack-6.1.4.1/lib/action_controller/metal.rb:190:in `dispatch'
actionpack-6.1.4.1/lib/action_controller/metal.rb:254:in `dispatch'
actionpack-6.1.4.1/lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack-6.1.4.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack-6.1.4.1/lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack-6.1.4.1/lib/action_dispatch/journey/router.rb:32:in `each'
actionpack-6.1.4.1/lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack-6.1.4.1/lib/action_dispatch/routing/route_set.rb:842:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:71:in `call'
rack-2.2.3/lib/rack/tempfile_reaper.rb:15:in `call'
rack-2.2.3/lib/rack/conditional_get.rb:40:in `call'
rack-2.2.3/lib/rack/head.rb:12:in `call'
actionpack-6.1.4.1/lib/action_dispatch/http/permissions_policy.rb:22:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:358:in `call'
rack-2.2.3/lib/rack/session/abstract/id.rb:266:in `context'
rack-2.2.3/lib/rack/session/abstract/id.rb:260:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/cookies.rb:689:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport-6.1.4.1/lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack-6.1.4.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
logster-2.10.1/lib/logster/middleware/reporter.rb:43:in `call'
railties-6.1.4.1/lib/rails/rack/logger.rb:37:in `call_app'
railties-6.1.4.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:23:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/request_id.rb:26:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:23:in `call'
rack-2.2.3/lib/rack/method_override.rb:24:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
rack-2.2.3/lib/rack/sendfile.rb:110:in `call'
actionpack-6.1.4.1/lib/action_dispatch/middleware/host_authorization.rb:92:in `call'
rack-mini-profiler-3.0.0/lib/mini_profiler/profiler.rb:249:in `call'
message_bus-4.2.0/lib/message_bus/rack/middleware.rb:60:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:202:in `call'
railties-6.1.4.1/lib/rails/engine.rb:539:in `call'
railties-6.1.4.1/lib/rails/railtie.rb:207:in `public_send'
railties-6.1.4.1/lib/rails/railtie.rb:207:in `method_missing'
rack-2.2.3/lib/rack/urlmap.rb:74:in `block in call'
rack-2.2.3/lib/rack/urlmap.rb:58:in `each'
rack-2.2.3/lib/rack/urlmap.rb:58:in `call'
unicorn-6.1.0/lib/unicorn/http_server.rb:634:in `process_client'
unicorn-6.1.0/lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn-6.1.0/lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn-6.1.0/lib/unicorn/http_server.rb:143:in `start'
unicorn-6.1.0/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/bin/unicorn:25:in `load'
/var/www/discourse/vendor/bundle/ruby/2.7.0/bin/unicorn:25:in `<main>'

이 정보가 도움이 될까요?
저는 이 게시글들을 수리하기 위해 할 수 있는 모든 것을 하고 있지만, 어쩌면 이것은 제 쪽의 문제가 아니라 Discourse 자체와 관련이 있는 것 같다는 생각이 들기 시작합니다. :person_shrugging:


수정: 아래에 자동으로 링크된 게시글을 참조하세요.


문제 해결:

이제 저는 모든 게시글을 다시 베이킹(rebake)하기만 하면 됩니다. :wink:


또 다른 수정:

확실히 효과가 있었을 것이고, 여전히 오래된 일반 URL을 가진 이미지에도 적용될 것입니다. 하지만:

  • 모든 오래된 Imageshack 깨진 링크가 Imageshack 자체에서 우크라이나 국기를 표시하는 유효한 이미지로 대체되었기 때문에, Discourse에 자동으로 업로드되어 URL이 마크다운 로컬 이미지 링크로 변경되었습니다.

  • 다행히도 이 모든 국기 이미지들은 동일한 링크(![](upload://sOlmOE8qRgLUJ8cCe6N1JNkDV3Y.jpeg) - 제 경우, 어쨌든 Discourse의 훌륭한 동작입니다 :+1:)를 가진 채로 Discourse에 업로드되었기 때문에, 이를 매우 쉽게 대상화하여 제거하거나 다른 것으로 교체할 수 있습니다. :slight_smile:

이것은 이주(migration) 후 저와 같은 문제에 직면할 사람들에게 알리기 위해 작성합니다.

4개의 좋아요

poll_option_total 값이 가끔 부정확한 것 같습니다. 옵션별 비익명 투표 수가 poll_option_total 값보다 많은 것을 확인했습니다. 그리고 해당 사용자들은 모두 존재합니다.

GREATEST(..., 0)을 사용하면 해결됩니다. 적어도 크래시는 발생하지 않습니다.

        SELECT o.poll_option_id, o.poll_option_text, o.poll_option_total AS total_votes,
          GREATEST(CAST(o.poll_option_total AS SIGNED) - (
            SELECT COUNT(DISTINCT v.vote_user_id)
              FROM #{@table_prefix}poll_votes v
                JOIN #{@table_prefix}users u ON (v.vote_user_id = u.user_id)
                JOIN #{@table_prefix}topics t ON (v.topic_id = t.topic_id)
              WHERE v.poll_option_id = o.poll_option_id AND v.topic_id = o.topic_id
          ),0) AS anonymous_votes
        FROM #{@table_prefix}poll_options o
        WHERE o.topic_id = #{topic_id}
        ORDER BY o.poll_option_id
3개의 좋아요

우리 회사에서 사용하는 phpbb 3.3 포럼을 Discourse로 마이그레이션하고 싶습니다. 이 기능이 언제 지원될지 아시는 분이 계신가요?

1개의 좋아요
3개의 좋아요

와, 정말 대단하네요! 감사합니다!

1개의 좋아요

이 문제에 대해 새 스레드를 시작해야 한다면 미리 사과드립니다.

서브폴더에 phpBB 포럼을 운영하고 있습니다:

thedomain.com/forum/

phpBB에서 서브도메인에 있는 Discourse로 이관하기 위해 import 스크립트를 사용할 계획입니다. 즉:

forum.thedomain.com

따라서 도메인과 영구 링크(permalinks) 관련해서는 새 사이트에서 HTTPS를 사용하여 settings.yml에 다음 설정을 적용하면 되는 것 같습니다:

site_prefix:
    # 게시물 내 내부 링크 재작성(rewriting)에 필요합니다
    original: thdomain.com/forum    # http(s):// 제외
    new: https://forum.thedomain.com       # http:// 또는 https:// 포함

  # 기존 포럼 링크를 새 위치로 리다이렉트하려면 이 설정을 활성화하세요.
  permalinks:
    categories: true  # /viewforum.php?f=1            을  /c/category-name(으)로 리다이렉트
    topics: true      # /viewtopic.php?f=6&t=43       을  /t/topic-name/81(으)로 리다이렉트
    posts: true      # /viewtopic.php?p=2455#p2455   을  /t/topic-name/81/4(으)로 리다이렉트
    # 각 유형의 링크 앞에 접두사를 추가합니다. 예: 'forum'을 추가하면 /forum/viewtopic.php?f=6&t=43이 /t/topic-name/81(으)로 리다이렉트됩니다.
    # 포럼이 서브폴더에 설치되어 있지 않았다면 비워 두세요.
    prefix: forum

그리고 RewriteEngine이 이미 활성화된 Apache를 실행하는 원본 서버의 .htaccess 파일에는 다음이 필요합니다:

RewriteCond %{HTTP_HOST} ^thedomain.com
RewriteRule ^forum/(.*)$ https://forum.thedomain.com/$1 [L,R=301]

정말 이 정도면 쉬운 것이라면, 이 스크립트는 훌륭합니다! :grinning:

추가로 몇 가지 질문이 있습니다:

  1. 영구 링크 설정에서 게시물(posts)은 "false"로 설정되어 있습니다. 특정 게시물로 가는 링크가 외부에 존재하므로, 이것들도 영구 링크로 설정하고 싶습니다. 성능 등의 이유로 true로 설정하지 말아야 할 이유가 있을까요?
  2. prefix 값은 큰따옴표 없이 사용하는 것이 괜찮은가요, 아니면 주석에 나와 있듯이 따옴표를 붙여야 하나요?
2개의 좋아요

수입 속도가 약간 느려질 수 있지만, 걱정하지 않아도 됩니다. 거의 필요하지 않기 때문에 기본적으로 비활성화되어 있는 경우가 대부분입니다.

네, 괜찮습니다.

2개의 좋아요

이 데이터를 가져오는 준비를 하던 중 막힌 부분이 있습니다.

마이그레이션할 phpBB 포럼은 phpBB 외부의 디렉터리(하지만 서버의 동일한 사용자 계정 아래)에 연도별 폴더로 저장된 이미지를 위한 HTML img 태그를 생성하는 커스텀 BB코드를 사용하고 있습니다. 이 BB코드는 다음과 같은 형식을 따릅니다:

[Gallery]{NUMBER1}|{NUMBER2}|{NUMBER3}|{SIMPLETEXT}[/Gallery]

여기서 {NUMBER1}과 {NUMBER2}는 각각 이미지의 너비와 높이를 나타내는 정수입니다. {NUMBER3}은 이미지가 저장된 연도 폴더를 나타내는 정수이고, {SIMPLETEXT}는 이미지 파일 이름입니다. 이 BB코드의 HTML 대체 형태는 다음과 같습니다:

<img class="postimage gallery-image" src="/gallery/files/{NUMBER3}/{SIMPLETEXT}" width="{NUMBER1}" height="{NUMBER2}" />

제가 알아내야 할 것은 마이그레이션 스크립트에서 이 커스텀 BB코드를 어떻게 처리할 것인가입니다. 구체적으로 커스텀 BB코드를 Discourse에서 사용할 수 있는 것으로 변환하는 방법과, 가져오기(file tree)에서 이미지 파일을 어디에 배치할지 결정하는 것입니다.

Ruby-BBcode-to-MD를 살펴봤는데, 이 프로젝트는 "tags.rb 파일을 편집하여 이 세트에 커스텀 태그를 쉽게 확장할 수 있습니다"라고 설명하고 있습니다. tags.rb 파일도 확인해 봤지만, Ruby 코드를 처음 보는 저로서는 tags.rb 파일에 포함된 공식 BB코드(가이드로 사용할 수 있는 것들)와 파이프(|)로 구분되는 형식이 다르기 때문에 커스텀 BB코드를 어떻게 다뤄야 할지 막막한 상태입니다.

아직 templates/import/phpbb3.template.yml을 로드하지 않았기 때문에, 이 파일이 Ruby BBcode to MD gem을 추가해 주는 것은 아닌가 추측하고 있습니다.

따라서 다음과 같은 질문이 있습니다:

  1. 마이그레이션을 위해 이 커스텀 BB코드를 처리하는 가장 좋은 방법은 무엇인가요? tags.rb 파일을 편집하는 것이 올바른 방향인가요? (그렇다면 Ruby 코딩과 정규식(regex)에 대해 조사해 보겠지만, 어떤 힌트라도 환영합니다!)
  2. 이 갤러리의 이미지 파일이 Discourse에 저장되고 가져온 게시물에 표시되도록 하기 위해 가져오기 파일 트리에서 이미지 파일을 배치하는 가장 좋은 위치는 어디인가요?
1개의 좋아요

해당 gem은 실제로 더 이상 사용되지 않습니다. 어떤 버전의 phpBB에서 가져오고 계신가요? v3.1 이하의 경우 discourse/script/import_scripts/phpbb3/support/text_processor.rb at ea2fd75d10e81687334f8d29e0d3e786dbdb4a53 · discourse/discourse · GitHub 파일에 정규식(regex) 처리를 적용해야 합니다.

v3.2의 경우 discourse/script/import_scripts/phpbb3/support/bbcode/xml_to_markdown.rb at a71b219c9a18ad418e330282fde511bcb79ba7c4 · discourse/discourse · GitHub 파일에 BBCode 처리 로직을 추가할 수 있습니다.

2개의 좋아요