forked from cybrespace/mastodon
		
	Adding sync of follow relationships to Neo4J, accounts/suggestions API
This commit is contained in:
		
							parent
							
								
									91144d46ec
								
							
						
					
					
						commit
						e21a3fe0cd
					
				
					 11 changed files with 76 additions and 5 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -21,3 +21,4 @@ public/assets
 | 
				
			||||||
.env
 | 
					.env
 | 
				
			||||||
.env.*
 | 
					.env.*
 | 
				
			||||||
node_modules/
 | 
					node_modules/
 | 
				
			||||||
 | 
					neo4j/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								Gemfile
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								Gemfile
									
										
									
									
									
								
							| 
						 | 
					@ -39,6 +39,7 @@ gem 'will_paginate'
 | 
				
			||||||
gem 'rack-attack'
 | 
					gem 'rack-attack'
 | 
				
			||||||
gem 'sidekiq'
 | 
					gem 'sidekiq'
 | 
				
			||||||
gem 'ledermann-rails-settings'
 | 
					gem 'ledermann-rails-settings'
 | 
				
			||||||
 | 
					gem 'neography'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gem 'react-rails'
 | 
					gem 'react-rails'
 | 
				
			||||||
gem 'browserify-rails'
 | 
					gem 'browserify-rails'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								Gemfile.lock
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								Gemfile.lock
									
										
									
									
									
								
							| 
						 | 
					@ -97,6 +97,7 @@ GEM
 | 
				
			||||||
      dotenv (= 2.1.1)
 | 
					      dotenv (= 2.1.1)
 | 
				
			||||||
      railties (>= 4.0, < 5.1)
 | 
					      railties (>= 4.0, < 5.1)
 | 
				
			||||||
    erubis (2.7.0)
 | 
					    erubis (2.7.0)
 | 
				
			||||||
 | 
					    excon (0.53.0)
 | 
				
			||||||
    execjs (2.7.0)
 | 
					    execjs (2.7.0)
 | 
				
			||||||
    fabrication (2.15.2)
 | 
					    fabrication (2.15.2)
 | 
				
			||||||
    fast_blank (1.0.0)
 | 
					    fast_blank (1.0.0)
 | 
				
			||||||
| 
						 | 
					@ -165,13 +166,21 @@ GEM
 | 
				
			||||||
    mime-types-data (3.2016.0521)
 | 
					    mime-types-data (3.2016.0521)
 | 
				
			||||||
    mimemagic (0.3.0)
 | 
					    mimemagic (0.3.0)
 | 
				
			||||||
    mini_portile2 (2.1.0)
 | 
					    mini_portile2 (2.1.0)
 | 
				
			||||||
    minitest (5.9.0)
 | 
					    minitest (5.9.1)
 | 
				
			||||||
    multi_json (1.12.1)
 | 
					    multi_json (1.12.1)
 | 
				
			||||||
 | 
					    neography (1.8.0)
 | 
				
			||||||
 | 
					      excon (>= 0.33.0)
 | 
				
			||||||
 | 
					      json (>= 1.7.7)
 | 
				
			||||||
 | 
					      multi_json (>= 1.3.2)
 | 
				
			||||||
 | 
					      os (>= 0.9.6)
 | 
				
			||||||
 | 
					      rake (>= 0.8.7)
 | 
				
			||||||
 | 
					      rubyzip (>= 1.0.0)
 | 
				
			||||||
    nio4r (1.2.1)
 | 
					    nio4r (1.2.1)
 | 
				
			||||||
    nokogiri (1.6.8.1)
 | 
					    nokogiri (1.6.8.1)
 | 
				
			||||||
      mini_portile2 (~> 2.1.0)
 | 
					      mini_portile2 (~> 2.1.0)
 | 
				
			||||||
    oj (2.17.3)
 | 
					    oj (2.17.3)
 | 
				
			||||||
    orm_adapter (0.5.0)
 | 
					    orm_adapter (0.5.0)
 | 
				
			||||||
 | 
					    os (0.9.6)
 | 
				
			||||||
    ostatus2 (1.0.1)
 | 
					    ostatus2 (1.0.1)
 | 
				
			||||||
      addressable (~> 2.4)
 | 
					      addressable (~> 2.4)
 | 
				
			||||||
      http (~> 2.0)
 | 
					      http (~> 2.0)
 | 
				
			||||||
| 
						 | 
					@ -236,7 +245,7 @@ GEM
 | 
				
			||||||
      rake (>= 0.8.7)
 | 
					      rake (>= 0.8.7)
 | 
				
			||||||
      thor (>= 0.18.1, < 2.0)
 | 
					      thor (>= 0.18.1, < 2.0)
 | 
				
			||||||
    rainbow (2.1.0)
 | 
					    rainbow (2.1.0)
 | 
				
			||||||
    rake (11.2.2)
 | 
					    rake (11.3.0)
 | 
				
			||||||
    rdoc (4.2.2)
 | 
					    rdoc (4.2.2)
 | 
				
			||||||
      json (~> 1.4)
 | 
					      json (~> 1.4)
 | 
				
			||||||
    react-rails (1.8.2)
 | 
					    react-rails (1.8.2)
 | 
				
			||||||
| 
						 | 
					@ -281,6 +290,7 @@ GEM
 | 
				
			||||||
      ruby-progressbar (~> 1.7)
 | 
					      ruby-progressbar (~> 1.7)
 | 
				
			||||||
      unicode-display_width (~> 1.0, >= 1.0.1)
 | 
					      unicode-display_width (~> 1.0, >= 1.0.1)
 | 
				
			||||||
    ruby-progressbar (1.8.1)
 | 
					    ruby-progressbar (1.8.1)
 | 
				
			||||||
 | 
					    rubyzip (1.2.0)
 | 
				
			||||||
    safe_yaml (1.0.4)
 | 
					    safe_yaml (1.0.4)
 | 
				
			||||||
    sass (3.4.22)
 | 
					    sass (3.4.22)
 | 
				
			||||||
    sass-rails (5.0.6)
 | 
					    sass-rails (5.0.6)
 | 
				
			||||||
| 
						 | 
					@ -370,6 +380,7 @@ DEPENDENCIES
 | 
				
			||||||
  letter_opener
 | 
					  letter_opener
 | 
				
			||||||
  link_header
 | 
					  link_header
 | 
				
			||||||
  lograge
 | 
					  lograge
 | 
				
			||||||
 | 
					  neography
 | 
				
			||||||
  nokogiri
 | 
					  nokogiri
 | 
				
			||||||
  oj
 | 
					  oj
 | 
				
			||||||
  ostatus2
 | 
					  ostatus2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								app/assets/javascripts/components/actions/suggestions.jsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/assets/javascripts/components/actions/suggestions.jsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					import api from '../api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const SUGGESTIONS_FETCH_REQUEST = 'SUGGESTIONS_FETCH_REQUEST';
 | 
				
			||||||
 | 
					export const SUGGESTIONS_FETCH_SUCCESS = 'SUGGESTIONS_FETCH_SUCCESS';
 | 
				
			||||||
 | 
					export const SUGGESTIONS_FETCH_FAIL    = 'SUGGESTIONS_FETCH_FAIL';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function fetchSuggestions() {
 | 
				
			||||||
 | 
					  return (dispatch, getState) => {
 | 
				
			||||||
 | 
					    api(getState).get('/api/v1/accounts/suggestions').then(response => {
 | 
				
			||||||
 | 
					      console.log(response.data);
 | 
				
			||||||
 | 
					    }).catch(error => {
 | 
				
			||||||
 | 
					      console.error(error);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
class Api::V1::AccountsController < ApiController
 | 
					class Api::V1::AccountsController < ApiController
 | 
				
			||||||
  before_action :doorkeeper_authorize!
 | 
					  before_action :doorkeeper_authorize!
 | 
				
			||||||
  before_action :set_account, except: :verify_credentials
 | 
					  before_action :set_account, except: [:verify_credentials, :suggestions]
 | 
				
			||||||
  respond_to    :json
 | 
					  respond_to    :json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,10 @@ class Api::V1::AccountsController < ApiController
 | 
				
			||||||
    @followers = @account.followers
 | 
					    @followers = @account.followers
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def suggestions
 | 
				
			||||||
 | 
					    @accounts = FollowSuggestion.get(current_user.account_id)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def statuses
 | 
					  def statuses
 | 
				
			||||||
    @statuses = @account.statuses.with_includes.with_counters.paginate_by_max_id(20, params[:max_id], params[:since_id]).to_a
 | 
					    @statuses = @account.statuses.with_includes.with_counters.paginate_by_max_id(20, params[:max_id], params[:since_id]).to_a
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,4 +22,28 @@ class Follow < ApplicationRecord
 | 
				
			||||||
  def title
 | 
					  def title
 | 
				
			||||||
    destroyed? ? "#{account.acct} is no longer following #{target_account.acct}" : "#{account.acct} started following #{target_account.acct}"
 | 
					    destroyed? ? "#{account.acct} is no longer following #{target_account.acct}" : "#{account.acct} started following #{target_account.acct}"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  after_create  :add_to_graph
 | 
				
			||||||
 | 
					  after_destroy :remove_from_graph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def add_to_graph
 | 
				
			||||||
 | 
					    neo = Neography::Rest.new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a = neo.create_unique_node('account_index', 'Account', account_id.to_s, account_id: account_id)
 | 
				
			||||||
 | 
					    b = neo.create_unique_node('account_index', 'Account', target_account_id.to_s, account_id: target_account_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    neo.create_unique_relationship('follow_index', 'Follow', id.to_s, 'follows', a, b)
 | 
				
			||||||
 | 
					  rescue Neography::NeographyError => e
 | 
				
			||||||
 | 
					    Rails.logger.error e
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def remove_from_graph
 | 
				
			||||||
 | 
					    neo = Neography::Rest.new
 | 
				
			||||||
 | 
					    rel = neo.get_relationship_index('follow_index', 'Follow', id.to_s)
 | 
				
			||||||
 | 
					    neo.delete_relationship(rel)
 | 
				
			||||||
 | 
					  rescue Neography::NeographyError => e
 | 
				
			||||||
 | 
					    Rails.logger.error e
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								app/models/follow_suggestion.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/models/follow_suggestion.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					class FollowSuggestion
 | 
				
			||||||
 | 
					  def self.get(for_account_id)
 | 
				
			||||||
 | 
					    neo = Neography::Rest.new
 | 
				
			||||||
 | 
					    account_ids = neo.execute_query('START a=node:account_index(Account={id}) MATCH (a)-[:follows]->(b)-[:follows]->(c) WHERE a <> c AND NOT (a)-[:follows]->(c) RETURN DISTINCT c.account_id', id: for_account_id)
 | 
				
			||||||
 | 
					    Account.where(id: account_ids['data'].first) unless account_ids.empty?
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										2
									
								
								app/views/api/v1/accounts/suggestions.rabl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/api/v1/accounts/suggestions.rabl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					collection @accounts
 | 
				
			||||||
 | 
					extends('api/v1/accounts/show')
 | 
				
			||||||
| 
						 | 
					@ -22,8 +22,8 @@ module Mastodon
 | 
				
			||||||
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
 | 
					    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
 | 
				
			||||||
    # config.i18n.default_locale = :de
 | 
					    # config.i18n.default_locale = :de
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
 | 
					    # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
 | 
				
			||||||
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
 | 
					    # config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config.active_job.queue_adapter = :sidekiq
 | 
					    config.active_job.queue_adapter = :sidekiq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								config/initializers/neography.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config/initializers/neography.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					Neography.configure do |config|
 | 
				
			||||||
 | 
					  config.protocol             = "http"
 | 
				
			||||||
 | 
					  config.server               = ENV['NEO4J_HOST'] || 'localhost'
 | 
				
			||||||
 | 
					  config.port                 = ENV['NEO4J_PORT'] || 7474
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -73,6 +73,7 @@ Rails.application.routes.draw do
 | 
				
			||||||
        collection do
 | 
					        collection do
 | 
				
			||||||
          get :relationships
 | 
					          get :relationships
 | 
				
			||||||
          get :verify_credentials
 | 
					          get :verify_credentials
 | 
				
			||||||
 | 
					          get :suggestions
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        member do
 | 
					        member do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue