From 8f4b7c1820b046c8df10e043a0bc605f3007eee7 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Sat, 20 May 2017 11:32:44 -0400 Subject: [PATCH] Filter languages with opt out (#3175) * Remove allowed_languages and add filtered_languages * Use filtered_languages instead of allowed_languages --- app/controllers/settings/preferences_controller.rb | 2 +- app/javascript/styles/forms.scss | 2 +- app/models/account.rb | 2 +- app/models/status.rb | 6 +++--- app/models/user.rb | 4 ++-- app/views/settings/preferences/show.html.haml | 2 +- config/locales/simple_form.ar.yml | 2 -- config/locales/simple_form.en.yml | 2 +- config/locales/simple_form.fa.yml | 2 -- config/locales/simple_form.he.yml | 2 -- config/locales/simple_form.ja.yml | 3 --- config/locales/simple_form.oc.yml | 3 --- config/locales/simple_form.pl.yml | 2 -- config/locales/simple_form.pt-BR.yml | 2 -- config/locales/simple_form.th.yml | 4 +--- config/locales/simple_form.zh-CN.yml | 2 -- .../20170520145338_change_language_filter_to_opt_out.rb | 9 +++++++++ db/schema.rb | 6 +++--- spec/controllers/settings/preferences_controller_spec.rb | 6 +++--- spec/models/status_spec.rb | 4 ++-- spec/models/user_spec.rb | 4 ++-- 21 files changed, 30 insertions(+), 41 deletions(-) create mode 100644 db/migrate/20170520145338_change_language_filter_to_opt_out.rb diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 04a85849da..28757d1bcf 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -26,7 +26,7 @@ class Settings::PreferencesController < ApplicationController def user_params params.require(:user).permit( :locale, - allowed_languages: [] + filtered_languages: [] ) end diff --git a/app/javascript/styles/forms.scss b/app/javascript/styles/forms.scss index ce31f01af7..db60e1e106 100644 --- a/app/javascript/styles/forms.scss +++ b/app/javascript/styles/forms.scss @@ -352,7 +352,7 @@ code { } } -.user_allowed_languages { +.user_filtered_languages { li { float: left; width: 50%; diff --git a/app/models/account.rb b/app/models/account.rb index 726e6c127c..7e4291d55c 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -99,7 +99,7 @@ class Account < ApplicationRecord prefix: true, allow_nil: true - delegate :allowed_languages, to: :user, prefix: false, allow_nil: true + delegate :filtered_languages, to: :user, prefix: false, allow_nil: true def local? domain.nil? diff --git a/app/models/status.rb b/app/models/status.rb index a4e581a066..d7304152f5 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -142,8 +142,8 @@ class Status < ApplicationRecord before_validation :set_conversation class << self - def in_allowed_languages(account) - where(language: account.allowed_languages) + def not_in_filtered_languages(account) + where.not(language: account.filtered_languages) end def as_home_timeline(account) @@ -234,7 +234,7 @@ class Status < ApplicationRecord def filter_timeline_for_account(query, account, local_only) query = query.not_excluded_by_account(account) query = query.not_domain_blocked_by_account(account) unless local_only - query = query.in_allowed_languages(account) if account.allowed_languages.present? + query = query.not_in_filtered_languages(account) if account.filtered_languages.present? query.merge(account_silencing_filter(account)) end diff --git a/app/models/user.rb b/app/models/user.rb index 7cf3a1290e..2ad68f9aeb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -30,7 +30,7 @@ # otp_required_for_login :boolean # last_emailed_at :datetime # otp_backup_codes :string is an Array -# allowed_languages :string default([]), not null, is an Array +# filtered_languages :string default([]), not null, is an Array # class User < ApplicationRecord @@ -83,6 +83,6 @@ class User < ApplicationRecord private def sanitize_languages - allowed_languages.reject!(&:blank?) + filtered_languages.reject!(&:blank?) end end diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index b64fd7c969..0532d1dc8c 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -12,7 +12,7 @@ label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale - = f.input :allowed_languages, + = f.input :filtered_languages, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index bc41c9fae7..5b45c1bb26 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -12,8 +12,6 @@ ar: data: ملف CSV تم تصديره من خادوم مثيل آخر لماستدون sessions: otp: أدخل الرمز الثنائي من هاتفك أو استخدم أحد رموز الاسترداد. - user: - allowed_languages: سوف يتم السماح بعرض اللغات المختارة على خيوطك المتسلسلة العامة أما التي لم يتم تحديدها فسوف تصفّى. labels: defaults: avatar: الصورة الرمزية diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 74dc16efea..ec74ff70db 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -17,7 +17,7 @@ en: sessions: otp: Enter the Two-factor code from your phone or use one of your recovery codes. user: - allowed_languages: These languages will be allowed in your public timelines. Languages that are not selected will be filtered out. + filtered_languages: Selected languages will be removed from your public timelines. labels: defaults: avatar: Avatar diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index e3c59fa4ab..77c043c5f3 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -12,8 +12,6 @@ fa: data: پروندهٔ CSV که از سرور ماستدون دیگری برون‌سپاری شده sessions: otp: کد تأیید دومرحله‌ای را از تلفن خود وارد کنید یا یکی از کدهای بازیابی را به کار ببرید. - user: - allowed_languages: این زبان‌ها در فهرست عمومی نوشته‌ها مجاز خواهند بود. زبان‌هایی که انتخاب نشده باشند به این فهرست راه پیدا نمی‌کنند. labels: defaults: avatar: تصویر نمایه diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 0f0949e87d..e72d7f2bd5 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -16,8 +16,6 @@ he: data: 'קובץ CSV שיוצא משרת מסטודון אחר' sessions: otp: 'נא להקליד קוד אימות דו-שלבי ממכשירך או קוד אחזור גישה.' - user: - allowed_languages: אלו השפות שיהיה מותרות בצירי הזמן הציבוריים שלך. שפות שלא ייבחרו יפולטרו מעיני הקוראים. labels: defaults: avatar: תמונת פרופיל diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 811e474fef..c048577959 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -12,11 +12,8 @@ ja: data: 他の Mastodon インスタンスからエクスポートしたCSVファイルを選択して下さい sessions: otp: 携帯電話に表示された2段階認証コードを入力するか、生成したリカバリーコードを使用してください。 - user: - allowed_languages: 選択した言語があなたの公開タイムラインに表示されます。選択していない言語は取り除かれます。 labels: defaults: - allowed_languages: 許可する言語 avatar: アイコン confirm_new_password: 新しいパスワード(確認用) confirm_password: パスワード(確認用) diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml index 088a9393aa..d5a209271f 100644 --- a/config/locales/simple_form.oc.yml +++ b/config/locales/simple_form.oc.yml @@ -12,11 +12,8 @@ oc: data: Fichièr CSV exportat d’una autra instància Mastodon sessions: otp: Picatz lo còdi d’autentificacion en dos temps (Two factor code) de vòstre mobil o utilizatz un de vòstres còdis de recuperacion. - user: - allowed_languages: Aquestas lengas seràn las que seràn autorizadas dins vòstre flux public. Las lengas pas causidas seràn rescondudas. labels: defaults: - allowed_languages: Lengas autorizadas avatar: Avatar confirm_new_password: Confirmacion del nòu senhal confirm_password: Confirmatz lo nòu senhal diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index 2d750b02c4..40c4b73a8c 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -12,8 +12,6 @@ pl: data: Plik CSV wyeksportowany z innej instancji Mastodona sessions: otp: Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych. - user: - allowed_languages: Te języki będą wyświetlać się na Twojej osi czasu. Wpisy w niezaznaczonych językach nie będą widoczne. labels: defaults: avatar: Awatar diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 82c9000f1d..1cbf6ea577 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -12,8 +12,6 @@ pt-BR: data: Arquivo CSV exportado de outra instancia Mastodon sessions: otp: Entre com o código de 2 passos do seu telefone ou use os códiogos de recuperação. - user: - allowed_languages: Essas línguas vão ser permitidas na sua timeline pública. Línguas que não forem selecionadas serão filtradas. labels: defaults: avatar: Avatar diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index 388886bf0f..de206fe0dc 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -9,15 +9,13 @@ th: other: '%{count} characters left' header: PNG, GIF or JPG. At most 2MB. Will be downscaled to 700x335px locked: Requires you to manually approve followers and defaults post privacy to followers-only - note: + note: one: '1 character left' other: '%{count} characters left' imports: data: CSV file exported from another Mastodon instance sessions: otp: Enter the Two-factor code from your phone or use one of your recovery codes. - user: - allowed_languages: These languages will be allowed in your public timelines. Languages that are not selected will be filtered out. labels: defaults: avatar: Avatar diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index ed05eb38dc..7e9fd6d85e 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -12,8 +12,6 @@ zh-CN: data: 自其他服务站导出的 CSV 文件 sessions: otp: 输入你手机生成的两步验证码,或者恢复代码。 - user: - allowed_languages: 允许下列语言的内容出现在你的公共时间线上。 labels: defaults: avatar: 头像 diff --git a/db/migrate/20170520145338_change_language_filter_to_opt_out.rb b/db/migrate/20170520145338_change_language_filter_to_opt_out.rb new file mode 100644 index 0000000000..8dac98ee87 --- /dev/null +++ b/db/migrate/20170520145338_change_language_filter_to_opt_out.rb @@ -0,0 +1,9 @@ +class ChangeLanguageFilterToOptOut < ActiveRecord::Migration[5.0] + def change + remove_index :users, :allowed_languages + remove_column :users, :allowed_languages + + add_column :users, :filtered_languages, :string, array: true, default: [], null: false + add_index :users, :filtered_languages, using: :gin + end +end diff --git a/db/schema.rb b/db/schema.rb index 8246e665a8..33c8336156 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170517205741) do +ActiveRecord::Schema.define(version: 20170520145338) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -350,11 +350,11 @@ ActiveRecord::Schema.define(version: 20170517205741) do t.boolean "otp_required_for_login" t.datetime "last_emailed_at" t.string "otp_backup_codes", array: true - t.string "allowed_languages", default: [], null: false, array: true + t.string "filtered_languages", default: [], null: false, array: true t.index ["account_id"], name: "index_users_on_account_id", using: :btree - t.index ["allowed_languages"], name: "index_users_on_allowed_languages", using: :gin t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree t.index ["email"], name: "index_users_on_email", unique: true, using: :btree + t.index ["filtered_languages"], name: "index_users_on_filtered_languages", using: :gin t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree end diff --git a/spec/controllers/settings/preferences_controller_spec.rb b/spec/controllers/settings/preferences_controller_spec.rb index 6805a2ce0c..38e43f211b 100644 --- a/spec/controllers/settings/preferences_controller_spec.rb +++ b/spec/controllers/settings/preferences_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Settings::PreferencesController do render_views - let(:user) { Fabricate(:user, allowed_languages: []) } + let(:user) { Fabricate(:user, filtered_languages: []) } before do sign_in user, scope: :user @@ -18,12 +18,12 @@ describe Settings::PreferencesController do describe 'PUT #update' do it 'updates the user record' do - put :update, params: { user: { locale: 'en', allowed_languages: ['es', 'fr', ''] } } + put :update, params: { user: { locale: 'en', filtered_languages: ['es', 'fr', ''] } } expect(response).to redirect_to(settings_preferences_path) user.reload expect(user.locale).to eq 'en' - expect(user.allowed_languages).to eq ['es', 'fr'] + expect(user.filtered_languages).to eq ['es', 'fr'] end it 'updates user settings' do diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index e9e55a92bb..d3a66134b2 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -512,7 +512,7 @@ RSpec.describe Status, type: :model do context 'with language preferences' do it 'excludes statuses in languages not allowed by the account user' do - user = Fabricate(:user, allowed_languages: [:en, :es]) + user = Fabricate(:user, filtered_languages: [:fr]) @account.update(user: user) en_status = Fabricate(:status, language: 'en') es_status = Fabricate(:status, language: 'es') @@ -525,7 +525,7 @@ RSpec.describe Status, type: :model do end it 'includes all languages when user does not have a setting' do - user = Fabricate(:user, allowed_languages: []) + user = Fabricate(:user, filtered_languages: []) @account.update(user: user) en_status = Fabricate(:status, language: 'en') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 04c39de3b2..c3e924fd81 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -24,9 +24,9 @@ RSpec.describe User, type: :model do end it 'cleans out empty string from languages' do - user = Fabricate.build(:user, allowed_languages: ['']) + user = Fabricate.build(:user, filtered_languages: ['']) user.valid? - expect(user.allowed_languages).to eq [] + expect(user.filtered_languages).to eq [] end end