diff --git a/Gemfile b/Gemfile index 57ea00cc835..9b9bd40f2fa 100644 --- a/Gemfile +++ b/Gemfile @@ -88,7 +88,7 @@ gem 'sidekiq-scheduler', '~> 6.0' gem 'sidekiq-unique-jobs', '> 8' gem 'simple_form', '~> 5.2' gem 'simple-navigation', '~> 4.4' -gem 'stoplight', '~> 4.1' +gem 'stoplight' gem 'strong_migrations' gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' @@ -146,7 +146,7 @@ group :test do gem 'climate_control' # Validate schemas in specs - gem 'json-schema', '~> 5.0' + gem 'json-schema', '~> 6.0' # Test harness fo rack components gem 'rack-test', '~> 2.1' diff --git a/Gemfile.lock b/Gemfile.lock index 111837de739..098168f006c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -365,7 +365,7 @@ GEM json-ld-preloaded (3.3.2) json-ld (~> 3.3) rdf (~> 3.3) - json-schema (5.2.1) + json-schema (6.0.0) addressable (~> 2.8) bigdecimal (~> 3.1) jsonapi-renderer (0.2.2) @@ -719,9 +719,7 @@ GEM redis (4.8.1) redis-client (0.25.2) connection_pool - redlock (1.3.2) - redis (>= 3.0.0, < 6.0) - regexp_parser (2.11.0) + regexp_parser (2.11.1) reline (0.6.2) io-console (~> 0.5) request_store (1.7.0) @@ -751,7 +749,7 @@ GEM rspec-mocks (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (8.0.1) + rspec-rails (8.0.2) actionpack (>= 7.2) activesupport (>= 7.2) railties (>= 7.2) @@ -789,7 +787,7 @@ GEM lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.38.0, < 2.0) - rubocop-rails (2.32.0) + rubocop-rails (2.33.1) activesupport (>= 4.2.0) lint_roller (~> 1.1) rack (>= 1.1) @@ -855,8 +853,8 @@ GEM stackprof (0.2.27) starry (0.2.0) base64 - stoplight (4.1.1) - redlock (~> 1.0) + stoplight (5.3.1) + zeitwerk stringio (3.1.7) strong_migrations (2.5.0) activerecord (>= 7.1) @@ -1005,7 +1003,7 @@ DEPENDENCIES jd-paperclip-azure (~> 3.0) json-ld json-ld-preloaded (~> 3.2) - json-schema (~> 5.0) + json-schema (~> 6.0) kaminari (~> 1.2) kt-paperclip (~> 7.2) letter_opener (~> 1.8) @@ -1088,7 +1086,7 @@ DEPENDENCIES simplecov (~> 0.22) simplecov-lcov (~> 0.8) stackprof - stoplight (~> 4.1) + stoplight strong_migrations test-prof thor (~> 1.2) diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 0350114280c..1383e6ac78e 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -24,11 +24,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController super(&:build_invite_request) end - def edit # rubocop:disable Lint/UselessMethodDefinition + def edit super end - def create # rubocop:disable Lint/UselessMethodDefinition + def create super end diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index b61a569860f..2bdd3558643 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -9,6 +9,8 @@ module SignatureVerification EXPIRATION_WINDOW_LIMIT = 12.hours CLOCK_SKEW_MARGIN = 1.hour + STOPLIGHT_COOL_OFF_TIME = 5.minutes.seconds + STOPLIGHT_THRESHOLD = 1 def require_account_signature! render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account @@ -107,10 +109,12 @@ module SignatureVerification end def stoplight_wrapper - Stoplight("source:#{request.remote_ip}") - .with_threshold(1) - .with_cool_off_time(5.minutes.seconds) - .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) } + Stoplight( + "source:#{request.remote_ip}", + cool_off_time: STOPLIGHT_COOL_OFF_TIME, + threshold: STOPLIGHT_THRESHOLD, + tracked_errors: [HTTP::Error, OpenSSL::SSL::SSLError] + ) end def actor_refresh_key!(actor) diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.jsx b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx index cf5bae2e074..35733ac23b6 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.jsx +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx @@ -25,7 +25,7 @@ export const ReplyIndicator = () => {
- +
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 58c3f1fa574..26417dc0eb8 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -224,6 +224,7 @@ "confirmations.discard_draft.edit.message": "Kontynuowanie spowoduje utratę wszystkich zmian wprowadzonych przez Ciebie w aktualnie edytowanym poście.", "confirmations.discard_draft.edit.title": "Odrzucić zmiany w poście?", "confirmations.discard_draft.post.cancel": "Wznów wersję roboczą", + "confirmations.discard_draft.post.message": "Kontynuacja odrzuci aktualnie tworzony post.", "confirmations.discard_draft.post.title": "Anulować wersję roboczą?", "confirmations.discard_edit_media.confirm": "Odrzuć", "confirmations.discard_edit_media.message": "Masz niezapisane zmiany w opisie lub podglądzie, odrzucić je mimo to?", @@ -244,6 +245,9 @@ "confirmations.remove_from_followers.confirm": "Usuń obserwującego", "confirmations.remove_from_followers.message": "{name} przestanie Cię obserwować. Czy na pewno chcesz kontynuować?", "confirmations.remove_from_followers.title": "Usunąć obserwującego?", + "confirmations.revoke_quote.confirm": "Usuń post", + "confirmations.revoke_quote.message": "Tej akcji nie można cofnąć.", + "confirmations.revoke_quote.title": "Usuń post?", "confirmations.unfollow.confirm": "Nie obserwuj", "confirmations.unfollow.message": "Czy na pewno nie chcesz obserwować {name}?", "confirmations.unfollow.title": "Cofnąć obserwację?", @@ -305,6 +309,9 @@ "emoji_button.search_results": "Wyniki wyszukiwania", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Podróże i miejsca", + "empty_column.account_featured.me": "Niczego jeszcze nie poleciłeś. Czy wiesz, że możesz wyświetlać swoje hashtagi, z których korzystasz najbardziej, a nawet konta znajomego na swoim profilu?", + "empty_column.account_featured.other": "{acct} nie wyróżnił jeszcze nic. Czy wiesz, że możesz wyświetlać swoje hashtagi, z których korzystasz najbardziej, a nawet konta znajomego na swoim profilu?", + "empty_column.account_featured_other.unknown": "To konto nie zostało jeszcze wyróżnione.", "empty_column.account_hides_collections": "Ta osoba postanowiła nie udostępniać tych informacji", "empty_column.account_suspended": "Konto zawieszone", "empty_column.account_timeline": "Brak wpisów!", @@ -560,6 +567,8 @@ "navigation_bar.follows_and_followers": "Obserwowani i obserwujący", "navigation_bar.import_export": "Import i eksport", "navigation_bar.lists": "Listy", + "navigation_bar.live_feed_local": "Kanał na żywo (lokalny)", + "navigation_bar.live_feed_public": "Kanał na żywo (publiczny)", "navigation_bar.logout": "Wyloguj", "navigation_bar.moderation": "Moderacja", "navigation_bar.more": "Więcej", @@ -594,6 +603,7 @@ "notification.label.mention": "Wzmianka", "notification.label.private_mention": "Wzmianka bezpośrednia", "notification.label.private_reply": "Komentarz bezpośredni", + "notification.label.quote": "{name} cytował twój post", "notification.label.reply": "Komentarz", "notification.mention": "Wzmianka", "notification.mentioned_you": "{name} wzmiankuje cię", @@ -651,6 +661,7 @@ "notifications.column_settings.mention": "Wzmianki:", "notifications.column_settings.poll": "Wyniki ankiety:", "notifications.column_settings.push": "Powiadomienia push", + "notifications.column_settings.quote": "Cytaty:", "notifications.column_settings.reblog": "Podbicia:", "notifications.column_settings.show": "Pokaż w kolumnie", "notifications.column_settings.sound": "Odtwarzaj dźwięk", @@ -871,6 +882,8 @@ "status.quote_error.filtered": "Ukryte z powodu jednego z Twoich filtrów", "status.quote_error.not_available": "Post niedostępny", "status.quote_error.pending_approval": "Post oczekujący", + "status.quote_error.pending_approval_popout.body": "Oferty współdzielone przez Fediverse mogą wymagać czasu, ponieważ różne serwery mają różne protokoły.", + "status.quote_error.pending_approval_popout.title": "Oczekujący cytat? Spokojnie, bądź cierpliwy :)", "status.quote_post_author": "Zacytowano post @{name}", "status.read_more": "Czytaj dalej", "status.reblog": "Podbij", @@ -886,6 +899,7 @@ "status.reply": "Odpowiedz", "status.replyAll": "Odpowiedz na wątek", "status.report": "Zgłoś @{name}", + "status.revoke_quote": "Usuń mój wpis z postu @{name}", "status.sensitive_warning": "Wrażliwa zawartość", "status.share": "Udostępnij", "status.show_less_all": "Zwiń wszystkie", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index ada27cea5fd..219149239a6 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -245,6 +245,9 @@ "confirmations.remove_from_followers.confirm": "Убрать подписчика", "confirmations.remove_from_followers.message": "Пользователь {name} перестанет быть подписан на вас. Продолжить?", "confirmations.remove_from_followers.title": "Убрать подписчика?", + "confirmations.revoke_quote.confirm": "Убрать пост", + "confirmations.revoke_quote.message": "Это действие невозможно отменить.", + "confirmations.revoke_quote.title": "Убрать пост?", "confirmations.unfollow.confirm": "Отписаться", "confirmations.unfollow.message": "Вы уверены, что хотите отписаться от {name}?", "confirmations.unfollow.title": "Отписаться?", @@ -498,6 +501,8 @@ "keyboard_shortcuts.translate": "перевести пост", "keyboard_shortcuts.unfocus": "убрать фокус с поля ввода/поиска", "keyboard_shortcuts.up": "вверх по списку", + "learn_more_link.got_it": "Понятно", + "learn_more_link.learn_more": "Узнать больше", "lightbox.close": "Закрыть", "lightbox.next": "Далее", "lightbox.previous": "Назад", @@ -845,6 +850,8 @@ "status.bookmark": "Добавить в закладки", "status.cancel_reblog_private": "Отменить продвижение", "status.cannot_reblog": "Этот пост не может быть продвинут", + "status.context.load_new_replies": "Доступны новые ответы", + "status.context.loading": "Проверяем, есть ли еще ответы", "status.continued_thread": "Продолжение предыдущего поста", "status.copy": "Скопировать ссылку на пост", "status.delete": "Удалить", @@ -871,6 +878,7 @@ "status.open": "Открыть пост", "status.pin": "Закрепить в профиле", "status.quote_error.filtered": "Скрыто одним из ваших фильтров", + "status.quote_error.not_available": "Пост недоступен", "status.read_more": "Читать далее", "status.reblog": "Продвинуть", "status.reblog_private": "Продвинуть для своей аудитории", diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 023eef19a02..0da1335b5cc 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -74,7 +74,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end def update_interaction_policies! - @status.quote_approval_policy = @status_parser.quote_policy + @status.update(quote_approval_policy: @status_parser.quote_policy) end def update_media_attachments! diff --git a/app/services/bulk_import_row_service.rb b/app/services/bulk_import_row_service.rb index 26909dfe04f..ac5080f0ba4 100644 --- a/app/services/bulk_import_row_service.rb +++ b/app/services/bulk_import_row_service.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true class BulkImportRowService + STOPLIGHT_COOL_OFF_TIME = 5.minutes.seconds + STOPLIGHT_THRESHOLD = 1 + def call(row) @account = row.bulk_import.account @data = row.data @@ -10,7 +13,7 @@ class BulkImportRowService when :following, :blocking, :muting, :lists target_acct = @data['acct'] target_domain = domain(target_acct) - @target_account = stoplight_wrapper(target_domain).run { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) } + @target_account = stoplight_wrapper(target_domain).run(stoplight_fallback) { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) } return false if @target_account.nil? when :bookmarks target_uri = @data['uri'] @@ -18,7 +21,7 @@ class BulkImportRowService @target_status = ActivityPub::TagManager.instance.uri_to_resource(target_uri, Status) return false if @target_status.nil? && ActivityPub::TagManager.instance.local_uri?(target_uri) - @target_status ||= stoplight_wrapper(target_domain).run { ActivityPub::FetchRemoteStatusService.new.call(target_uri) } + @target_status ||= stoplight_wrapper(target_domain).run(stoplight_fallback) { ActivityPub::FetchRemoteStatusService.new.call(target_uri) } return false if @target_status.nil? end @@ -51,13 +54,18 @@ class BulkImportRowService TagManager.instance.local_domain?(domain) ? nil : TagManager.instance.normalize_domain(domain) end + def stoplight_fallback + ->(error) {} + end + def stoplight_wrapper(domain) if domain.present? - Stoplight("source:#{domain}") - .with_fallback { nil } - .with_threshold(1) - .with_cool_off_time(5.minutes.seconds) - .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) } + Stoplight( + "source:#{domain}", + cool_off_time: STOPLIGHT_COOL_OFF_TIME, + threshold: STOPLIGHT_THRESHOLD, + tracked_errors: [HTTP::Error, OpenSSL::SSL::SSLError] + ) else Stoplight('domain-blank') end diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb index 7a1440ed15f..40b5c42404f 100644 --- a/app/workers/activitypub/delivery_worker.rb +++ b/app/workers/activitypub/delivery_worker.rb @@ -5,8 +5,8 @@ class ActivityPub::DeliveryWorker include RoutingHelper include JsonLdHelper + STOPLIGHT_COOL_OFF_TIME = 60 STOPLIGHT_FAILURE_THRESHOLD = 10 - STOPLIGHT_COOLDOWN = 60 sidekiq_options queue: 'push', retry: 16, dead: false @@ -75,9 +75,11 @@ class ActivityPub::DeliveryWorker end def stoplight_wrapper - Stoplight(@inbox_url) - .with_threshold(STOPLIGHT_FAILURE_THRESHOLD) - .with_cool_off_time(STOPLIGHT_COOLDOWN) + Stoplight( + @inbox_url, + cool_off_time: STOPLIGHT_COOL_OFF_TIME, + threshold: STOPLIGHT_FAILURE_THRESHOLD + ) end def failure_tracker diff --git a/config/initializers/stoplight.rb b/config/initializers/stoplight.rb index 0ade504f67b..c92a4693039 100644 --- a/config/initializers/stoplight.rb +++ b/config/initializers/stoplight.rb @@ -3,6 +3,8 @@ require 'stoplight' Rails.application.reloader.to_prepare do - Stoplight.default_data_store = Stoplight::DataStore::Redis.new(RedisConnection.new.connection) - Stoplight.default_notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)] + Stoplight.configure do |config| + config.data_store = Stoplight::DataStore::Redis.new(RedisConnection.new.connection) + config.notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)] + end end diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 29de53637cd..32ea9f26c3b 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -599,6 +599,7 @@ pl: limited: Ograniczone title: Moderacja moderation_notes: + create: Dodaj notatkę moderacyjną title: Notatki moderacyjne private_comment: Prywatny komentarz public_comment: Publiczny komentarz @@ -1109,6 +1110,7 @@ pl: trending: Popularne username_blocks: add_new: Dodaj nową + block_registrations: Zablokuj rejestracje comparison: contains: Zawiera equals: Równa się @@ -1742,6 +1744,9 @@ pl: title: Nowe wspomnienie o Tobie poll: subject: Ankieta %{name} zakończyła się + quote: + subject: "%{name} cytował twój post" + title: Nowy cytat reblog: body: 'Twój wpis został podbity przez %{name}:' subject: Twój wpis został podbity przez %{name} @@ -2024,6 +2029,9 @@ pl: does_not_match_previous_name: nie pasuje do poprzedniej nazwy terms_of_service: title: Regulamin + terms_of_service_interstitial: + review_link: Przeglądnij Warunki Korzystania + title: Warunki korzystania z %{domain} zmieniają się themes: contrast: Mastodon (Wysoki kontrast) default: Mastodon (Ciemny) diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 001e48c650c..58f71bb4549 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -196,6 +196,7 @@ ru: create_relay: Создание ретранслятора create_unavailable_domain: Добавление домена в список недоступных create_user_role: Создание ролей + create_username_block: Создать правило имени пользователя demote_user: Разжалование пользователей destroy_announcement: Удаление объявлений destroy_canonical_email_block: Удаление блокировок e-mail @@ -209,6 +210,7 @@ ru: destroy_status: Удаление постов destroy_unavailable_domain: Исключение доменов из списка недоступных destroy_user_role: Удаление ролей + destroy_username_block: Удалить правило имени пользователя disable_2fa_user: Отключение 2FA disable_custom_emoji: Отключение эмодзи disable_relay: Отключение ретранслятора @@ -243,6 +245,7 @@ ru: update_report: Изменение жалоб update_status: Изменение постов update_user_role: Изменение ролей + update_username_block: Обновить правило имени пользователя actions: approve_appeal_html: "%{name} одобрил(а) обжалование действий модерации от %{target}" approve_user_html: "%{name} утвердил(а) регистрацию %{target}" @@ -261,6 +264,7 @@ ru: create_relay_html: "%{name} создал(а) ретранслятор %{target}" create_unavailable_domain_html: "%{name} приостановил доставку на узел %{target}" create_user_role_html: "%{name} создал(а) роль %{target}" + create_username_block_html: "%{name} создал(а) правило для имён пользователей, содержащих %{target}" demote_user_html: "%{name} разжаловал(а) пользователя %{target}" destroy_announcement_html: "%{name} удалил(а) объявление %{target}" destroy_canonical_email_block_html: "%{name} снял(а) блокировку e-mail с хэшем %{target}" @@ -274,6 +278,7 @@ ru: destroy_status_html: "%{name} удалил(а) пост пользователя %{target}" destroy_unavailable_domain_html: "%{name} возобновил доставку на узел %{target}" destroy_user_role_html: "%{name} удалил(а) роль %{target}" + destroy_username_block_html: "%{name} удалил(а) правило для имён пользователей, содержащих %{target}" disable_2fa_user_html: "%{name} отключил(а) требование двухэтапной авторизации для пользователя %{target}" disable_custom_emoji_html: "%{name} отключил(а) эмодзи %{target}" disable_relay_html: "%{name} отключил(а) ретранслятор %{target}" @@ -308,6 +313,7 @@ ru: update_report_html: "%{name} изменил(а) жалобу %{target}" update_status_html: "%{name} изменил(а) пост пользователя %{target}" update_user_role_html: "%{name} изменил(а) роль %{target}" + update_username_block_html: "%{name} обновил(а) правило для имён пользователей, содержащих %{target}" deleted_account: удалённая учётная запись empty: Журнал пуст. filter_by_action: Фильтр по действию @@ -499,15 +505,24 @@ ru: fasp: debug: callbacks: + created_at: Создано в delete: Удалить ip: IP-адрес + request_body: Тело запроса providers: + active: Активен base_url: Основной URL delete: Удалить + edit: Редактировать поставщика + finish_registration: Завершить регистрацию + name: Имя + providers: Поставщики + registration_requested: Требуется регистрация registrations: confirm: Подтвердить reject: Отклонить save: Сохранить + select_capabilities: Выберите возможности sign_in: status: Пост title: FASP @@ -585,6 +600,9 @@ ru: all: Все limited: Ограниченные title: Модерация + moderation_notes: + create: Добавить заметку модератора + title: Заметки модератора private_comment: Приватный комментарий public_comment: Публичный комментарий purge: Удалить данные @@ -799,11 +817,16 @@ ru: title: Роли rules: add_new: Добавить правило + add_translation: Добавить перевод delete: Удалить description_html: Хотя большинство утверждает, что прочитали и согласны с условиями обслуживания, обычно люди не читают их до тех пор, пока не возникнет проблема. Упростите просмотр правил вашего сервера с первого взгляда, предоставив их в виде простого маркированного списка. Старайтесь, чтобы отдельные правила были краткими и простыми, но старайтесь не разбивать их на множество отдельных элементов. edit: Редактировать правило empty: Правила сервера еще не определены. + move_down: Переместить вниз + move_up: Переместить вверх title: Правила сервера + translation: Перевод + translations: Переводы settings: about: manage_rules: Управление правилами на сервере @@ -829,6 +852,7 @@ ru: discovery: follow_recommendations: Рекомендации подписок preamble: Наблюдение интересного контента играет важную роль при открытии новых пользователей, которые могут не знать ни одного Mastodon. Контролируйте как работают различные функции обнаружения на вашем сервере. + privacy: Конфиденциальность profile_directory: Каталог профилей public_timelines: Публичные ленты publish_statistics: Опубликовать стаитстику @@ -1087,6 +1111,23 @@ ru: other: За последнюю неделю использовал %{count} человек title: Рекомендации и тренды trending: Популярное + username_blocks: + add_new: Добавить новое + block_registrations: Блокировать регистрации + comparison: + contains: Содержит + equals: Равен + contains_html: Содержит %{string} + created_msg: Успешно создано правило имени пользователя + delete: Удалить + edit: + title: Редактировать правило имени пользователя + matches_exactly_html: Равен %{string} + new: + create: Создать правило + title: Создать новое правило имени пользователя + not_permitted: Не разрешено + title: Правила имени пользователя warning_presets: add_new: Добавить delete: Удалить @@ -1705,6 +1746,10 @@ ru: title: Новое упоминание poll: subject: Опрос %{name} завершился + quote: + body: 'Ваш пост был процитирован %{name}:' + subject: "%{name} процитировал(а) ваш пост" + title: Новая цитата reblog: body: "%{name} продвинул(а) ваш пост:" subject: "%{name} продвинул(а) ваш пост" @@ -1987,6 +2032,10 @@ ru: does_not_match_previous_name: не совпадает с предыдущим именем terms_of_service: title: Пользовательское соглашение + terms_of_service_interstitial: + past_preamble_html: Мы изменили наше пользовательское соглашение с момента вашего последнего посещения. Мы рекомендуем вам ознакомиться с обновленным соглашением. + review_link: Посмотреть пользовательское соглашение + title: Изменяется пользовательское соглашение %{domain} themes: contrast: Mastodon (высококонтрастная) default: Mastodon (тёмная) diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index 6faef6aa9ca..23204dea2db 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -56,10 +56,12 @@ pl: scopes: Wybór API, do których aplikacja będzie miała dostęp. Jeżeli wybierzesz nadrzędny zakres, nie musisz wybierać jego elementów. setting_aggregate_reblogs: Nie pokazuj nowych podbić dla wpisów, które zostały niedawno podbite (dotyczy tylko nowo otrzymanych podbić) setting_always_send_emails: Powiadomienia e-mail zwykle nie będą wysyłane, gdy używasz Mastodon + setting_default_quote_policy: To ustawienie będzie skuteczne tylko dla postów utworzonych z następną wersją Mastodon, ale możesz wybrać swoje preferencje w przygotowaniu. setting_default_sensitive: Wrażliwe multimedia są domyślnie schowane i mogą być odkryte kliknięciem setting_display_media_default: Ukrywaj zawartość multimedialną oznaczoną jako wrażliwa setting_display_media_hide_all: Zawsze ukrywaj zawartość multimedialną setting_display_media_show_all: Zawsze pokazuj zawartość multimedialną + setting_emoji_style: Jak wyświetlić emotikony. "Auto" spróbuje użyć natywnych emoji, ale wróci do Twemoji dla starszych przeglądarek. setting_system_scrollbars_ui: Stosuje się tylko do przeglądarek komputerowych opartych na Safari i Chrome setting_use_blurhash: Gradienty są oparte na kolorach ukrywanej zawartości, ale uniewidaczniają wszystkie szczegóły setting_use_pending_items: Ukryj aktualizacje osi czasu za kliknięciem, zamiast automatycznego przewijania strumienia @@ -75,6 +77,7 @@ pl: filters: action: Wybierz akcję do wykonania, gdy post pasuje do filtra actions: + blur: Ukryj media za ostrzeżeniem, bez ukrywania samego tekstu hide: Całkowicie ukryj przefiltrowaną zawartość, jakby nie istniała warn: Ukryj filtrowaną zawartość za ostrzeżeniem wskazującym tytuł filtra form_admin_settings: @@ -88,6 +91,7 @@ pl: favicon: WEBP, PNG, GIF, albo JPEG. Nadpisuje domyślną faviconę Mastodona. mascot: Nadpisuje ilustrację w zaawansowanym interfejsie internetowym. media_cache_retention_period: Media z wpisów od obcych użytkowników są cache'owane na twoim serwerze. Kiedy dana wartość jest dodatnia, media te będą usunięte po tylu dniach. Jeżeli usunięte media zostaną potem zażądane, oryginał zostanie ponownie pobrany (o ile jest dalej dostępny). Z powodu ograniczeń dot. częstotliwości z jaką karty podglądu linków dopytują się o dane od stron trzecich, zalecana wartość to min. 14 dni, bo karty podglądu linków nie będą wcześniej odświeżane na żądane. + min_age: Użytkownicy zostaną poproszeni o potwierdzenie daty urodzenia podczas rejestracji peers_api_enabled: Lista nazw domen, z którymi ten serwer spotkał się w fediverse. Nie są tu zawarte żadne dane o tym, czy użytkownik dokonuje federacji z danym serwerem, a jedynie, że jego serwer o tym wie. Jest to wykorzystywane przez serwisy, które zbierają statystyki dotyczące federacji w ogólnym sensie. profile_directory: Katalog profili zawiera listę wszystkich użytkowników, którzy zgodzili się na bycie znalezionymi. require_invite_text: Kiedy rejestracje wymagają ręcznego zatwierdzenia, ustaw pole "Dlaczego chcesz dołączyć?" jako obowiązkowe, a nie opcjonalne @@ -132,13 +136,18 @@ pl: name: Możesz zmieniać tylko wielkość liter, np. aby były bardziej widoczne terms_of_service: changelog: Może być stworzony przy pomocy składni Markdown. + effective_date: Uzasadnione ramy czasowe mogą być różne w dowolnym miejscu od 10 do 30 dni od daty powiadomienia użytkowników. text: Może być stworzony przy pomocy składni Markdown. terms_of_service_generator: admin_email: Zawiadomienia prawne obejmują środki zapobiegawcze, nakazy sądowe, wnioski o popełnienie sprawy oraz wnioski organów ścigania. + arbitration_address: Czy może być taki sam jak adres fizyczny powyżej lub „N/A” jeśli używasz adresu e-mail. + arbitration_website: Może być formularzem internetowym lub „N/A”, jeśli używasz adresu e-mail. choice_of_law: Miasto, region, terytorium lub stan, którego wewnętrzne prawo będzie regulowało wszelkie roszczenia. dmca_address: W przypadku operatorów z USA należy użyć adresu zarejestrowanego w DMCA Designated Agent Directory. Lista skrytek pocztowych dostępna jest na bezpośrednią prośbę użytkownika. Użyj DMCA Agent Post Office Box Waiver Request, aby wysłać email do Copyright Office z informacją, że jesteś domowym administratorm treści i z powodu obawy o zemstę lub odwetu za swoje działania, musisz użyć skrytki pocztowej, żeby usunąć swój adres domowy z dostępu publicznego. + dmca_email: Czy może ten sam adres e-mail używany dla powyższego "Adres e-mail dla prawnych zawiadomień"? domain: Unikalny numer identyfikacji świadczonej przez Ciebie usługi online. jurisdiction: Wymień państwo, w którym mieszkają osoby płacące rachunki. Jeżeli jest to spółka lub inny zarejestrowany podmiot, w zależności od przypadku podaj państwo, w którym jest zarejestrowany, a także miasto, region czy województwo. + min_age: Nie powinien być niższy niż minimalny wiek wymagany przez prawo twojego państwa. user: chosen_languages: Jeżeli zaznaczone, tylko wpisy w wybranych językach będą wyświetlane na publicznych osiach czasu role: Rola kontroluje uprawnienia użytkownika. @@ -148,6 +157,10 @@ pl: name: Publiczna nazwa roli, jeśli włączone jest wyświetlanie odznaki permissions_as_keys: Użytkownicy z tą rolą będą mieli dostęp do... position: Wyższa rola decyduje o rozwiązywaniu konfliktów w pewnych sytuacjach. Niektóre działania mogą być wykonywane tylko na rolach z niższym priorytetem + username_block: + allow_with_approval: Zamiast bezwzględnie uniemożliwiać rejestrację, pasujące rejestracje będą wymagały Twojej zgody + comparison: Proszę pamiętać o problemie Scunthorpe podczas blokowania częściowych dopasowań + username: Będą dopasowane niezależnie od otoczki i zwykłych homoglików, takich jak "4" dla "a" lub "3" dla "e" webhook: events: Wybierz zdarzenia do wysłania template: Poskładaj zawartość JSON, podstawiając zmienne. Użyjemy domyślnej wartości, jeżeli pole zostawisz pustym. @@ -255,6 +268,7 @@ pl: name: Hasztag filters: actions: + blur: Ukryj media z ostrzeżeniem hide: Ukryj całkowicie warn: Ukryj z ostrzeżeniem form_admin_settings: @@ -312,6 +326,7 @@ pl: follow_request: Powiadamiaj mnie e-mailem, gdy ktoś poprosi o pozwolenie na obserwowanie mnie mention: Powiadamiaj mnie e-mailem, gdy ktoś o mnie wspomni pending_account: Wyślij e-mail kiedy nowe konto potrzebuje recenzji + quote: Ktoś Cię cytował reblog: Powiadamiaj mnie e-mailem, gdy ktoś podbije mój wpis report: Nowe zgłoszenie zostało wysłane software_updates: diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml index 5c48d751b55..3979d9c6dea 100644 --- a/config/locales/simple_form.ru.yml +++ b/config/locales/simple_form.ru.yml @@ -237,6 +237,7 @@ ru: setting_display_media_default: По умолчанию setting_display_media_hide_all: Скрывать все setting_display_media_show_all: Показывать все + setting_emoji_style: Стиль эмодзи setting_expand_spoilers: Разворачивать все посты с предупреждением о содержании setting_hide_network: Скрыть мои связи setting_missing_alt_text_modal: Запрашивать подтверждение при публикации медиа без альтернативного текста @@ -319,6 +320,7 @@ ru: follow_request: Мне пришёл запрос на подписку mention: Меня упомянули в посте pending_account: Новая заявка на создание аккаунта + quote: Кто-то процитировал вас reblog: Мой пост продвинули report: Новое обращение отправлено software_updates: @@ -365,6 +367,9 @@ ru: name: Название permissions_as_keys: Разрешения position: Приоритет + username_block: + allow_with_approval: Разрешить регистрацию с одобрением + comparison: Метод сравнения webhook: events: Включенные события template: Шаблон полезной нагрузки diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb index 401da112908..011e165ed74 100644 --- a/lib/paperclip/attachment_extensions.rb +++ b/lib/paperclip/attachment_extensions.rb @@ -73,8 +73,8 @@ module Paperclip @url_generator.for_as_default(style_name) end + STOPLIGHT_COOL_OFF_TIME = 30 STOPLIGHT_THRESHOLD = 10 - STOPLIGHT_COOLDOWN = 30 # We overwrite this method to put a circuit breaker around # calls to object storage, to stop hitting APIs that are slow @@ -84,11 +84,12 @@ module Paperclip # Don't go through Stoplight if we don't have anything object-storage-oriented to do return super if @queued_for_delete.empty? && @queued_for_write.empty? && !dirty? - Stoplight('object-storage') - .with_threshold(STOPLIGHT_THRESHOLD) - .with_cool_off_time(STOPLIGHT_COOLDOWN) - .with_error_handler { |error, handle| error.is_a?(Seahorse::Client::NetworkingError) ? handle.call(error) : raise(error) } - .run { super } + Stoplight( + 'object-storage', + cool_off_time: STOPLIGHT_COOL_OFF_TIME, + threshold: STOPLIGHT_THRESHOLD, + tracked_errors: [Seahorse::Client::NetworkingError] + ).run { super } end end end diff --git a/package.json b/package.json index de656d33c1d..6922dd435d3 100644 --- a/package.json +++ b/package.json @@ -170,7 +170,7 @@ "eslint-import-resolver-typescript": "^4.2.5", "eslint-plugin-formatjs": "^5.3.1", "eslint-plugin-import": "~2.32.0", - "eslint-plugin-jsdoc": "^52.0.0", + "eslint-plugin-jsdoc": "^53.0.0", "eslint-plugin-jsx-a11y": "~6.10.2", "eslint-plugin-promise": "~7.2.1", "eslint-plugin-react": "^7.37.4", diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 2503a58ac20..07d05d762f1 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -316,6 +316,23 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do expect(existing_status.edits).to_not be_empty end end + + context 'with an implicit update to quoting policy' do + let(:object) do + note.merge({ + 'content' => existing_status.text, + 'interactionPolicy' => { + 'canQuote' => { + 'automaticApproval' => ['https://www.w3.org/ns/activitystreams#Public'], + }, + }, + }) + end + + it 'updates status' do + expect(existing_status.reload.quote_approval_policy).to eq(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + end + end end end diff --git a/yarn.lock b/yarn.lock index 2795331617a..b6115435b51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2680,7 +2680,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^4.2.5" eslint-plugin-formatjs: "npm:^5.3.1" eslint-plugin-import: "npm:~2.32.0" - eslint-plugin-jsdoc: "npm:^52.0.0" + eslint-plugin-jsdoc: "npm:^53.0.0" eslint-plugin-jsx-a11y: "npm:~6.10.2" eslint-plugin-promise: "npm:~7.2.1" eslint-plugin-react: "npm:^7.37.4" @@ -6986,9 +6986,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^52.0.0": - version: 52.0.2 - resolution: "eslint-plugin-jsdoc@npm:52.0.2" +"eslint-plugin-jsdoc@npm:^53.0.0": + version: 53.0.1 + resolution: "eslint-plugin-jsdoc@npm:53.0.1" dependencies: "@es-joy/jsdoccomment": "npm:~0.52.0" are-docs-informative: "npm:^0.0.2" @@ -7002,7 +7002,7 @@ __metadata: spdx-expression-parse: "npm:^4.0.0" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/e36d8c75a5a100f71f4f5287ce12ffdf15474194b2877dbe1e06c3c24a1c0c0c7f13c2d92cb289a80515b6fe1e43c4c0b19814b5c5b22a46ac2ca7df23ab55ad + checksum: 10c0/d629863faa98026edc09535e8095669d97be4e77173bfe6cbe7ea0fcd641cd2537bec58e25db433cc6f4103d9a2a13c1bbb3916a8ed4ff05b18c566971dec472 languageName: node linkType: hard @@ -10308,8 +10308,8 @@ __metadata: linkType: hard "pino@npm:^9.0.0": - version: 9.7.0 - resolution: "pino@npm:9.7.0" + version: 9.8.0 + resolution: "pino@npm:9.8.0" dependencies: atomic-sleep: "npm:^1.0.0" fast-redact: "npm:^3.1.1" @@ -10324,7 +10324,7 @@ __metadata: thread-stream: "npm:^3.0.0" bin: pino: bin.js - checksum: 10c0/c7f8a83a9a9d728b4eff6d0f4b9367f031c91bcaa5806fbf0eedcc8e77faba593d59baf11a8fba0dd1c778bb17ca7ed01418ac1df4ec129faeedd4f3ecaff66f + checksum: 10c0/a6de40d8c777520a0f2bdd1727512db2dba51d0d8098500ec8326f1f95412e4e704ee4301287ccbbafbf7a7ab07999d5659333a7079d1b70341d0d69e4d40b29 languageName: node linkType: hard @@ -13898,8 +13898,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^7.1.1": - version: 7.1.1 - resolution: "vite@npm:7.1.1" + version: 7.1.2 + resolution: "vite@npm:7.1.2" dependencies: esbuild: "npm:^0.25.0" fdir: "npm:^6.4.6" @@ -13948,7 +13948,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/391a5c8b8f287b7b1653dedbe952fb4cb93bf7c99b19dab915cf63497892427198fef637e943a3391eacfecf7f2e8f55c40d0fa065fabdd885641430d0b74af7 + checksum: 10c0/4ed825b20bc0f49db99cd382de9506b2721ccd47dcebd4a68e0ef65e3cdd2347fded52b306c34178308e0fd7fe78fd5ff517623002cb00710182ad3012c92ced languageName: node linkType: hard