From 9d59d7b463e7f31ceedf27775a7ee3e8e071b4a1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Oct 2016 17:11:54 +0200 Subject: [PATCH] Adding a block model and filter mentions from blocked users (fix #60) --- app/controllers/application_controller.rb | 2 +- app/lib/feed_manager.rb | 8 ++++---- app/models/account.rb | 12 ++++++++++-- app/models/block.rb | 7 +++++++ app/models/stream_entry.rb | 2 +- app/services/precompute_feed_service.rb | 2 +- db/migrate/20161003145426_create_blocks.rb | 12 ++++++++++++ db/schema.rb | 10 +++++++++- spec/controllers/about_controller_spec.rb | 4 ++-- spec/fabricators/block_fabricator.rb | 3 +++ spec/models/block_spec.rb | 5 +++++ 11 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 app/models/block.rb create mode 100644 db/migrate/20161003145426_create_blocks.rb create mode 100644 spec/fabricators/block_fabricator.rb create mode 100644 spec/models/block_spec.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cd4b686f7..c8d7e2084 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,7 +10,7 @@ class ApplicationController < ActionController::Base rescue_from ActionController::RoutingError, with: :not_found rescue_from ActiveRecord::RecordNotFound, with: :not_found - before_action :store_current_location, :unless => :devise_controller? + before_action :store_current_location, unless: :devise_controller? def raise_not_found raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}" diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 779a31f0b..58d6a005c 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -40,13 +40,13 @@ class FeedManager end # Filter status out of the home feed if it is a reply to someone the user doesn't follow - def filter_from_home?(status, follower) + def filter_from_home?(status, receiver) replied_to_user = status.reply? ? status.thread.account : nil - (status.reply? && !(follower.id == replied_to_user.id || replied_to_user.id == status.account_id || follower.following?(replied_to_user))) + (status.reply? && !(receiver.id == replied_to_user.id || replied_to_user.id == status.account_id || receiver.following?(replied_to_user))) end - def filter_from_mentions?(status, follower) - false + def filter_from_mentions?(status, receiver) + receiver.blocking?(status.account) || (status.reblog? && receiver.blocking?(status.reblog.account)) end def inline_render(target_account, status) diff --git a/app/models/account.rb b/app/models/account.rb index 2fbd5a655..518b55f19 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -33,8 +33,12 @@ class Account < ApplicationRecord has_many :active_relationships, class_name: 'Follow', foreign_key: 'account_id', dependent: :destroy has_many :passive_relationships, class_name: 'Follow', foreign_key: 'target_account_id', dependent: :destroy - has_many :following, through: :active_relationships, source: :target_account - has_many :followers, through: :passive_relationships, source: :account + has_many :following, -> { order('follows.created_at desc') }, through: :active_relationships, source: :target_account + has_many :followers, -> { order('follows.created_at desc') }, through: :passive_relationships, source: :account + + # Block relationships + has_many :block_relationships, class_name: 'Block', foreign_key: 'account_id', dependent: :destroy + has_many :blocking, -> { order('blocks.created_at desc') }, through: :block_relationships, source: :target_account has_many :media_attachments, dependent: :destroy @@ -57,6 +61,10 @@ class Account < ApplicationRecord following.include?(other_account) end + def blocking?(other_account) + blocking.include?(other_account) + end + def local? domain.nil? end diff --git a/app/models/block.rb b/app/models/block.rb new file mode 100644 index 000000000..418afdbdf --- /dev/null +++ b/app/models/block.rb @@ -0,0 +1,7 @@ +class Block < ApplicationRecord + belongs_to :account + belongs_to :target_account, class_name: 'Account' + + validates :account, :target_account, presence: true + validates :account_id, uniqueness: { scope: :target_account_id } +end diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb index 261ecda53..0df7ece60 100644 --- a/app/models/stream_entry.rb +++ b/app/models/stream_entry.rb @@ -47,7 +47,7 @@ class StreamEntry < ApplicationRecord end def mentions - activity.respond_to?(:mentions) ? activity.mentions.map { |x| x.account } : [] + activity.respond_to?(:mentions) ? activity.mentions.map(&:account) : [] end def activity diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index cdeb4a92f..6b259fe80 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -7,7 +7,7 @@ class PrecomputeFeedService < BaseService instant_return = [] Status.send("as_#{type}_timeline", account).order('created_at desc').limit(FeedManager::MAX_ITEMS).find_each do |status| - next FeedManager.instance.filter?(type, status, account) + next if FeedManager.instance.filter?(type, status, account) redis.zadd(FeedManager.instance.key(type, account.id), status.id, status.id) instant_return << status unless instant_return.size > limit end diff --git a/db/migrate/20161003145426_create_blocks.rb b/db/migrate/20161003145426_create_blocks.rb new file mode 100644 index 000000000..14bae1e7f --- /dev/null +++ b/db/migrate/20161003145426_create_blocks.rb @@ -0,0 +1,12 @@ +class CreateBlocks < ActiveRecord::Migration[5.0] + def change + create_table :blocks do |t| + t.integer :account_id, null: false + t.integer :target_account_id, null: false + + t.timestamps null: false + end + + add_index :blocks, [:account_id, :target_account_id], unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index f835c21b8..c4421bec7 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: 20161003142332) do +ActiveRecord::Schema.define(version: 20161003145426) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -43,6 +43,14 @@ ActiveRecord::Schema.define(version: 20161003142332) do t.index ["username", "domain"], name: "index_accounts_on_username_and_domain", unique: true, using: :btree end + create_table "blocks", force: :cascade do |t| + t.integer "account_id", null: false + t.integer "target_account_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true, using: :btree + end + create_table "favourites", force: :cascade do |t| t.integer "account_id", null: false t.integer "status_id", null: false diff --git a/spec/controllers/about_controller_spec.rb b/spec/controllers/about_controller_spec.rb index 54b552b6f..4fb58637a 100644 --- a/spec/controllers/about_controller_spec.rb +++ b/spec/controllers/about_controller_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' RSpec.describe AboutController, type: :controller do - describe "GET #index" do - it "returns http success" do + describe 'GET #index' do + it 'returns http success' do get :index expect(response).to have_http_status(:success) end diff --git a/spec/fabricators/block_fabricator.rb b/spec/fabricators/block_fabricator.rb new file mode 100644 index 000000000..9a5a6808f --- /dev/null +++ b/spec/fabricators/block_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:block) do + +end diff --git a/spec/models/block_spec.rb b/spec/models/block_spec.rb new file mode 100644 index 000000000..6862de6fc --- /dev/null +++ b/spec/models/block_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Block, type: :model do + +end