Проблемы с миниатюрами из однобоксов Soundcloud и YouTube

Мы используем Topic List Previews (legacy) с плитками на главной странице. Вчера нам пришлось пересобрать наш инстанс по причинам, не связанным с TPL. Мы были осведомлены об изменении бэкенда для создания миниатюр в ядре Discourse и знали, что обновление может вызвать проблемы с миниатюрами. Тем не менее, это было необходимо. :slight_smile:

В любом случае, после пересборки (включая обновление Postgres) все миниатюры, генерируемые onebox-ами, исчезли. Это не проблема: мы пересоздали все посты, и большинство миниатюр вернулось (хорошо), но не все (интригующе и плохо). Мы пересоздали несколько постов ещё раз на всякий случай, но есть некоторые посты, у которых всё равно не появляется миниатюра на главной странице, даже если onebox-и корректно отображаются на странице темы.

Пока обнаружены два паттерна:

  • Onebox-ы Soundcloud отображаются без проблем, но миниатюра систематически отсутствует («Выбрать миниатюру» не показывает никаких вариантов), и пересборка HTML не решает эту проблему. Например, посмотрите https://the.eqlzr.org/t/female-pressure-podcast-episode-60-inverno/89.
  • Некоторые миниатюры YouTube onebox-ов отсутствовали на главной странице (только некоторые), а затем, после посещения страницы темы, они волшебным образом появлялись на главной. Однако…

Существует одна (и только одна, последняя) тема с YouTube onebox-ом, которая не генерирует миниатюру; не знаем почему: https://the.eqlzr.org/t/look-mom-no-computer-diy-synths/75.

Как обсуждалось, логика создания миниатюр теперь встроена в ядро.

То, что раньше приходилось делать TLP, в значительной степени больше не требуется.

Для справки, основные критерии включения следующие:

  def extract_images_for_post
    # все изображения с атрибутом src
    @doc.css("img[src]") -
    # минус эмодзи
    @doc.css("img.emoji") -
    # минус изображения внутри цитат
    @doc.css(".quote img") -
    # минус иконки сайтов onebox
    @doc.css("img.site-icon") -
    # минус аватары onebox
    @doc.css("img.onebox-avatar") -
    # минус маленькие изображения onebox (большие изображения — .aspect-image-full-size)
    @doc.css(".onebox .aspect-image img")
  end

из discourse/lib/cooked_post_processor.rb at main · discourse/discourse · GitHub

TLP немного модифицирует это, но только чтобы ослабить ограничения. Я хотел бы полностью отказаться от этого переопределения, если это возможно:

  def extract_images_for_post
    # все изображения с атрибутом src
    @doc.css("img[src]") -
    # минус эмодзи
    @doc.css("img.emoji") -
    # минус изображения внутри цитат
    @doc.css(".quote img") -
    # минус иконки сайтов onebox
    @doc.css("img.site-icon") -
    # минус аватары onebox
    @doc.css("img.onebox-avatar") # Более широкие критерии, чем в ядре Discourse
  end

из https://github.com/paviliondev/discourse-topic-previews/blob/master/lib/cooked_post_processor_edits.rb

Как видите, я сокращаю количество исключений, разрешая маленькие изображения onebox, как определено в ядре.

Вместо того чтобы поддерживать это в TLP, было бы лучше достичь консенсуса и паритета во всех сценариях использования, чтобы мне не приходилось поддерживать это в плагине вообще.

Это также актуально для вас, @Arkshine.

Спасибо, @merefield, это очень информативно.

Хочу отметить, что предыдущая реализация миниатюр для onebox Soundcloud давала отличные результаты, и этот регресс действительно беспокоит нас, так как наш сайт посвящён музыке. :slight_smile:

Меня не смущает, если мы иногда будем пропускать миниатюры YouTube.

Интересно, как это будет развиваться. Я согласен, что цель — тонкая настройка работы с миниатюрами в ядре Discourse, чтобы найти оптимальный баланс между множеством требований и пожеланий. Спасибо всем, кто работает над этим.

На первый взгляд, я не думаю, что это YouTube onebox. Подозреваю, что кто-то использовал в посте сырой код встраивания YouTube. Если преобразовать его в onebox, миниатюра должна появиться.

Раньше это работало со старым плагином TLP? Onebox для Soundcloud — это iframe, поэтому мне трудно представить, как мы могли бы извлечь из них изображение миниатюры, даже обновив наши критерии выбора. @merefield, был ли в TLP какой-то специфичный для Soundcloud код?

Да, вокруг oneboxes была реализована некоторая пользовательская логика, хотя она применялась не только к SoundCloud:

    if @has_oneboxes
      cooked = PrettyText.cook(@post.raw)

      if img
        ## Нам нужно что-то более конкретное для идентификации изображения
        img_id = img
        src = img.attribute("src").to_s
        img_id = src.split('/').last.split('.').first if src
      end

      prior_oneboxes = []
      Oneboxer.each_onebox_link(cooked) do |url, element|
        if !img || (img && cooked.index(element).to_i < cooked.index(img_id).to_i)
          html = Nokogiri::HTML::fragment(Oneboxer.cached_preview(url))
          prior_oneboxes = html.css('img')
        end
      end

      if prior_oneboxes.any?
        prior_oneboxes = prior_oneboxes.reject do |html|
          class_str = html.attribute('class').to_s
          class_str.include?('site-icon') || class_str.include?('avatar')
        end

        if prior_oneboxes.any? && validate_image_for_previews(prior_oneboxes.first)
          img = prior_oneboxes.first
        end
      end
   end

Эта логика была удалена, чтобы делегировать обработку основной логике ядра.

Ах, я и не подумал проверить исходный код. :slight_smile:

Это был onebox, но в URL был лишний аргумент:

https://www.youtube.com/watch?v=4T6J-K8_yk4&list=PLluPQLh1xzlL2agiCCQFClcsutli90Qnz

Я изменил его на обычный URL:

https://www.youtube.com/watch?v=4T6J-K8_yk4

Сразу ничего не изменилось. После перестройки HTML тоже не было мгновенного результата, но затем я проверил Sidekiq и увидел запланированную связанную задачу. После того как я терпеливо ждал 4 минуты, миниатюра теперь доступна и отображается на главной странице. Спасибо @david за такой быстрый ответ, да ещё и в воскресенье!

Безусловно. К сожалению, я не сделал ни одного скриншота. На главной странице изображение отображалось слева от onebox.

Интересно, я посмотрю на это на следующей неделе. Думаю, это всё ещё должно работать, даже с лишним аргументом.

А, понятно, значит вы извлекли HTML-код предпросмотра Onebox и извлекли из него миниатюры. Для SoundCloud это даёт миниатюру :+1:

Да, это основано на замечательном хаке от @angus :smiley: Я не несу никакой ответственности! Хотя работает отлично.

ОБНОВЛЕНИЕ: На самом деле, я вру — мои отпечатки пальцев тоже везде! Я написал часть этого кода так давно, что забыл о нём — это 2015 год!

Это обе сложные проблемы, и, на мой взгляд, пока мы оставим поведение без изменений. Возможно, в будущем мы сможем внести некоторые улучшения. Я создал несколько тем #feature для отслеживания прогресса.

По поводу различий с YouTube см.:

По поводу проблемы с SoundCloud см.:

У меня была та же проблема со ссылками YouTube в формате https://youtu.be/. После изменения их на формат https://www.youtube.com/watch?v= всё снова заработало.

Это странно, не могли бы вы поделиться здесь этими конкретными ссылками на YouTube? Должен сработать любой из форматов.

Возможно, перерисовка тоже решила бы проблему.
Но, похоже, она сохраняется в версиях:

Я сбросил ссылку на старую, и теперь всё отображается корректно. Похоже, это было связано с ошибкой рендеринга после обновления beta6.