flying-sphinx 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b115e7eb956584d31756788bc14b8119ec3e68ba
4
+ data.tar.gz: 28d21d5c1364dfe513d482d6463de1924c04469b
5
+ SHA512:
6
+ metadata.gz: 2921c3b5a1f2a8b2c5c7e962b290144581b46341c52b05685682798e84db1791bbedaed7a7e67aa45f9b5cc946829d4cafcf69b69d09ce08d85080a14e813655
7
+ data.tar.gz: 2ab0e472479c65c54157e50f08f6e7b8a4faa8c858f48c302fd5ddda9903c5513e163ccad20aff289c772190286babeec5998cc39c0d4330cacc19d05dee410d
data/.gitignore CHANGED
@@ -3,4 +3,5 @@ Gemfile.lock
3
3
  *.tmproj
4
4
  *.sublime-*
5
5
  gemfiles/*.lock
6
+ gemfiles/*.gemfile
6
7
  pkg
@@ -1,39 +1,15 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
- - ree
5
- - 1.9.3
6
- - 2.0
7
- - 2.1.2
8
- gemfile:
9
- - gemfiles/rails_2.3.gemfile
10
- - gemfiles/rails_3.0.gemfile
11
- - gemfiles/rails_3.2.gemfile
12
- - gemfiles/rails_4.0.gemfile
3
+ - 1.9.3
4
+ - 2.0
5
+ - 2.1.10
6
+ - 2.2.8
7
+ - 2.3.5
8
+ - 2.4.2
13
9
  before_install:
14
- - gem update --system
15
- - gem install bundler
16
- matrix:
17
- exclude:
18
- - rvm: 1.8.7
19
- gemfile: gemfiles/rails_4.0.gemfile
20
- - rvm: ree
21
- gemfile: gemfiles/rails_4.0.gemfile
22
- - rvm: 1.8.7
23
- gemfile: gemfiles/rails_3.2.gemfile
24
- - rvm: ree
25
- gemfile: gemfiles/rails_3.2.gemfile
26
- - rvm: 1.9.3
27
- gemfile: gemfiles/rails_2.3.gemfile
28
- - rvm: 2.0
29
- gemfile: gemfiles/rails_2.3.gemfile
30
- - rvm: 2.1.2
31
- gemfile: gemfiles/rails_2.3.gemfile
32
- - rvm: 1.9.3
33
- gemfile: gemfiles/rails_3.0.gemfile
34
- - rvm: 2.0
35
- gemfile: gemfiles/rails_3.0.gemfile
36
- - rvm: 2.1.2
37
- gemfile: gemfiles/rails_3.0.gemfile
10
+ - gem install bundler
11
+ - gem update --system
12
+ before_script:
13
+ - bundle exec appraisal install
38
14
  cache: bundler
39
- script: bundle exec rspec
15
+ script: bundle exec appraisal rspec
data/Appraisals CHANGED
@@ -1,23 +1,25 @@
1
- if RUBY_VERSION.to_f <= 1.8
2
- appraise 'rails-2.3' do
3
- gem 'rails', '~> 2.3.18'
4
- gem 'faraday', '0.7.0'
5
- gem 'riddle', '< 2.0.0'
6
- end
1
+ appraise 'rails-3.2' do
2
+ gem 'rails', '~> 3.2.18'
3
+ gem 'faraday', '~> 0.8.0'
4
+ end if RUBY_VERSION.to_f >= 1.9 && RUBY_VERSION.to_f <= 2.3
7
5
 
8
- appraise 'rails-3.0' do
9
- gem 'rails', '~> 3.0.20'
10
- gem 'faraday', '~> 0.8.0'
11
- gem 'riddle', '< 2.0.0'
12
- end
13
- else
14
- appraise 'rails-3.2' do
15
- gem 'rails', '~> 3.2.18'
16
- gem 'faraday', '~> 0.8.0'
17
- end
6
+ appraise 'rails-4.0' do
7
+ gem 'rails', '~> 4.0.5'
8
+ gem 'faraday', '~> 0.9.0'
9
+ end if RUBY_VERSION.to_f >= 1.9 && RUBY_VERSION.to_f <= 2.3
18
10
 
19
- appraise 'rails-4.0' do
20
- gem 'rails', '~> 4.0.5'
21
- gem 'faraday', '~> 0.9.0'
22
- end
23
- end
11
+ appraise 'rails-4.1' do
12
+ gem 'rails', '~> 4.1.16'
13
+ end if RUBY_VERSION.to_f >= 1.9 && RUBY_VERSION.to_f <= 2.3
14
+
15
+ appraise 'rails-4.2' do
16
+ gem 'rails', '~> 4.2.10'
17
+ end if RUBY_VERSION.to_f >= 1.9 && RUBY_VERSION.to_f <= 2.3
18
+
19
+ appraise 'rails-5.0' do
20
+ gem 'rails', '~> 5.0.6'
21
+ end if RUBY_VERSION.to_f >= 2.2
22
+
23
+ appraise 'rails-5.1' do
24
+ gem 'rails', '~> 5.1.4'
25
+ end if RUBY_VERSION.to_f >= 2.2
data/Gemfile CHANGED
@@ -2,20 +2,15 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'activesupport', '< 4.0.0' if RUBY_VERSION.to_f <= 1.8
6
- gem 'riddle', '< 2.0.0' if RUBY_VERSION.to_f <= 1.8
7
-
8
5
  if RUBY_VERSION.to_f <= 1.8
9
6
  gem "public_suffix", "< 1.4.0"
7
+ gem "nokogiri", "< 1.6.0"
8
+ gem "activesupport", "< 4.0.0"
10
9
  elsif RUBY_VERSION.to_f <= 1.9
11
10
  gem "public_suffix", "< 1.5.0"
11
+ gem "mime-types", "< 3.0"
12
+ gem "nokogiri", "< 1.7.0"
12
13
  elsif RUBY_VERSION.to_f <= 2.0
13
14
  gem "public_suffix", "< 1.5.0"
14
- else
15
- gem "public_suffix"
15
+ gem "nokogiri", "< 1.7.0"
16
16
  end
17
-
18
- gem 'appraisal', '~> 1.0.0',
19
- :git => 'git://github.com/thoughtbot/appraisal',
20
- :branch => 'master',
21
- :ref => 'bd6eef4b6a'
@@ -9,16 +9,18 @@ This is all covered pretty well on "the Flying Sphinx site":http://flying-sphinx
9
9
  <pre><code>gem 'flying-sphinx',
10
10
  :git => 'git://github.com/flying-sphinx/flying-sphinx.git',
11
11
  :branch => 'master',
12
- :ref => '6b691c2b43'</code></pre>
12
+ :ref => 'ab0dd5f047'</code></pre>
13
13
 
14
14
  h2. Compatibility and Limitations
15
15
 
16
16
  Flying Sphinx is built with support for Rails 2.3.6 and beyond. Sadly, earlier versions of Rails aren't supported due to a requirement of a recent version of Rack deep in the dependency tree.
17
17
 
18
- It works from Ruby 1.8.7 onwards, and on both Heroku's Bamboo and Cedar stacks. You _do_ need to use it with Heroku at this point - allowing others hosting elsewhere to use Flying Sphinx is something I'm considering, but it's not possible right now.
18
+ It works from Ruby 1.9.3 onwards, and on both Heroku's Bamboo and Cedar stacks. You _do_ need to use it with Heroku at this point - allowing others hosting elsewhere to use Flying Sphinx is something I'm considering, but it's not possible right now.
19
19
 
20
20
  There are limitations with Heroku's setup and Sphinx/Thinking Sphinx functionality - again, the official documentation "covers this":http://flying-sphinx.com/docs#limitations, so have a read there.
21
21
 
22
+ If you're still using Ruby 1.8.7, flying-sphinx 1.2.1 is the last release to support that.
23
+
22
24
  h2. Contributing
23
25
 
24
26
  Patches are indeed welcome - though I understand it's a little tricky to test them thoroughly. It's best to give your changes a spin on your Heroku app that's running Flying Sphinx (and if you don't have one of those, I'm a little confused as to why you're contributing).
@@ -38,4 +40,4 @@ h2. Contributors
38
40
 
39
41
  h2. Licence
40
42
 
41
- Copyright &copy; 2011-2012 Pat Allan, released under an MIT licence.
43
+ Copyright &copy; 2011-2017 Pat Allan, released under an MIT licence.
@@ -17,15 +17,19 @@ Gem::Specification.new do |s|
17
17
  s.require_paths = ['lib']
18
18
  s.executables = ['flying-sphinx']
19
19
 
20
- s.add_runtime_dependency 'thinking-sphinx'
21
- s.add_runtime_dependency 'riddle', '>= 1.5.6'
22
- s.add_runtime_dependency 'multi_json', '>= 1.3.0'
20
+ s.add_runtime_dependency 'ey-hmac', '~> 2.2'
23
21
  s.add_runtime_dependency 'faraday', '>= 0.7'
22
+ s.add_runtime_dependency 'gzipped_tar', '~> 0.0.3'
23
+ s.add_runtime_dependency 'multi_json', '>= 1.3.0'
24
24
  s.add_runtime_dependency 'pusher-client', '~> 0.3'
25
+ s.add_runtime_dependency 'riddle', '>= 1.5.6'
26
+ s.add_runtime_dependency 'thinking-sphinx', '>= 1.5.0'
25
27
 
28
+ s.add_development_dependency 'appraisal', '~> 2.2'
26
29
  s.add_development_dependency 'dotenv', '~> 0.11.1'
27
30
  s.add_development_dependency 'em-websocket', '~> 0.5.1'
28
31
  s.add_development_dependency 'mysql2', '~> 0.3.15'
32
+ s.add_development_dependency 'rack'
29
33
  s.add_development_dependency 'rspec', '~> 2.14'
30
34
  s.add_development_dependency 'rspec-retry', '~> 0.4'
31
35
  s.add_development_dependency 'webmock', '~> 1.17.4'
@@ -1,9 +1,12 @@
1
1
  require 'logger'
2
2
 
3
3
  module FlyingSphinx
4
+ module Request; end
4
5
  module Response; end
5
6
  module Translators; end
6
7
 
8
+ Error = Class.new StandardError
9
+
7
10
  @logger = Logger.new(STDOUT)
8
11
  @logger.level = Logger::INFO
9
12
  if ENV['VERBOSE_LOGGING'] && ENV['VERBOSE_LOGGING'] == 'true'
@@ -28,25 +31,28 @@ module FlyingSphinx
28
31
  end
29
32
 
30
33
  require 'multi_json'
34
+ require 'ey-hmac'
31
35
  require 'faraday'
36
+ require 'gzipped_tar'
32
37
  require 'riddle'
33
38
  require 'riddle/0.9.9'
34
39
  require 'pusher-client'
35
40
 
36
41
  PusherClient.logger = FlyingSphinx.logger
37
42
 
43
+ require 'flying_sphinx/version'
38
44
  require 'flying_sphinx/action'
39
45
  require 'flying_sphinx/api'
40
46
  require 'flying_sphinx/binary'
41
47
  require 'flying_sphinx/cli'
42
48
  require 'flying_sphinx/configuration'
43
49
  require 'flying_sphinx/configuration_options'
50
+ require 'flying_sphinx/configurer'
44
51
  require 'flying_sphinx/controller'
45
- require 'flying_sphinx/gzipped_hash'
46
52
  require 'flying_sphinx/setting_files'
47
53
  require 'flying_sphinx/sphinxql'
48
- require 'flying_sphinx/version'
49
54
 
55
+ require 'flying_sphinx/request/hmac'
50
56
  require 'flying_sphinx/response/invalid'
51
57
  require 'flying_sphinx/response/json'
52
58
  require 'flying_sphinx/response/logger'
@@ -62,7 +62,7 @@ class FlyingSphinx::Action
62
62
  def response
63
63
  attempts = 0
64
64
  @response ||= begin
65
- block.call.body
65
+ block.call
66
66
  rescue
67
67
  attempts += 1
68
68
  retry if attempts <= 3
@@ -7,8 +7,8 @@ class FlyingSphinx::API
7
7
  PUSHER_KEY = 'c5602d4909b5144321ce'
8
8
  end
9
9
 
10
- PATH = '/api/my/app'
11
- VERSION = 4
10
+ PATH = '/api/my/v5'
11
+ HEADERS = {'X-Flying-Sphinx-Version' => FlyingSphinx::Version}
12
12
 
13
13
  attr_reader :api_key, :identifier
14
14
 
@@ -19,17 +19,11 @@ class FlyingSphinx::API
19
19
  end
20
20
 
21
21
  def get(path, data = {})
22
- connection.get do |request|
23
- request.url normalize_path(path), data
24
- end
22
+ connection.get { |request| request.url normalize_path(path), data }.body
25
23
  end
26
24
 
27
25
  def post(path, data = {})
28
- connection.post normalize_path(path), data
29
- end
30
-
31
- def put(path, data = {})
32
- connection.put normalize_path(path), data
26
+ connection.post(normalize_path(path), data).body
33
27
  end
34
28
 
35
29
  private
@@ -41,27 +35,19 @@ class FlyingSphinx::API
41
35
  "#{PATH}#{path}"
42
36
  end
43
37
 
44
- def api_headers
45
- {
46
- 'Accept' => "application/vnd.flying-sphinx-v#{VERSION}+json",
47
- 'X-Flying-Sphinx-Token' => "#{identifier}:#{api_key}",
48
- 'X-Flying-Sphinx-Version' => FlyingSphinx::Version
49
- }
50
- end
51
-
52
38
  def connection(connection_options = {})
53
39
  options = {
54
40
  :ssl => {:verify => false},
55
41
  :url => SERVER,
56
- :headers => api_headers
42
+ :headers => HEADERS
57
43
  }
58
44
 
59
45
  Faraday.new(options) do |builder|
60
46
  # Built-in middleware
61
- builder.request :multipart
62
47
  builder.request :url_encoded
63
48
 
64
49
  # Local middleware
50
+ builder.use FlyingSphinx::Request::HMAC, identifier, api_key, 'Thebes'
65
51
  builder.use FlyingSphinx::Response::Logger
66
52
  builder.use FlyingSphinx::Response::Invalid
67
53
  builder.use FlyingSphinx::Response::JSON
@@ -63,7 +63,9 @@ class FlyingSphinx::CLI
63
63
  def load_rails
64
64
  return unless ENV['RAILS_ENV']
65
65
 
66
- require File.expand_path('config/boot', Dir.pwd)
66
+ boot = File.expand_path('config/boot', Dir.pwd)
67
+ return unless File.exist?("#{boot}.rb")
68
+ require boot
67
69
 
68
70
  if defined?(Rails) && !defined?(Rails::Railtie)
69
71
  require File.expand_path('config/environment', Dir.pwd)
@@ -29,7 +29,7 @@ class FlyingSphinx::Configuration
29
29
  attr_reader :identifier, :api_key
30
30
 
31
31
  def response_body
32
- @response_body ||= api.get('/').body
32
+ @response_body ||= api.get '/app'
33
33
  end
34
34
 
35
35
  def identifier_from_env
@@ -1,26 +1,23 @@
1
1
  class FlyingSphinx::ConfigurationOptions
2
- def to_hash
3
- {:sphinx_version => version, :configuration => gzipped_files_hash}
4
- end
5
-
6
- private
2
+ attr_reader :raw
7
3
 
8
- def configuration
9
- @configuration ||= ThinkingSphinx::Configuration.instance
4
+ def initialize(raw = nil, version = nil)
5
+ @raw = raw || FlyingSphinx.translator.sphinx_configuration
6
+ @version = version || '2.2.3'
10
7
  end
11
8
 
12
- def files_hash
13
- FlyingSphinx::SettingFiles.new.to_hash.merge(
14
- 'sphinx' => FlyingSphinx.translator.sphinx_configuration
15
- )
9
+ def settings
10
+ @settings ||= FlyingSphinx::SettingFiles.new.to_hash
16
11
  end
17
12
 
18
- def gzipped_files_hash
19
- FlyingSphinx::GzippedHash.new(files_hash).to_gzipped_hash
13
+ def version
14
+ version_defined? ? configuration.version : @version
20
15
  end
21
16
 
22
- def version
23
- version_defined? ? configuration.version : '2.0.4'
17
+ private
18
+
19
+ def configuration
20
+ @configuration ||= ThinkingSphinx::Configuration.instance
24
21
  end
25
22
 
26
23
  def version_defined?
@@ -0,0 +1,62 @@
1
+ class FlyingSphinx::Configurer
2
+ PresignatureError = Class.new FlyingSphinx::Error
3
+ UploadError = Class.new FlyingSphinx::Error
4
+
5
+ def initialize(api, input)
6
+ @api = api
7
+ @input = input
8
+ end
9
+
10
+ def call
11
+ if presignature["status"] != "OK"
12
+ raise PresignatureError, "Requesting presignature failed"
13
+ end
14
+
15
+ response = connection.post "", fields.merge(
16
+ "file" => Faraday::UploadIO.new(file, 'application/gzip', 'sphinx.tar.gz')
17
+ )
18
+
19
+ if response.status == 200
20
+ presignature["path"]
21
+ else
22
+ raise UploadError, "Uploading configuration failed"
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :api, :input
29
+
30
+ def connection
31
+ Faraday.new(:url => presignature["url"]) do |builder|
32
+ builder.request :multipart
33
+
34
+ builder.use FlyingSphinx::Response::Logger
35
+
36
+ builder.adapter Faraday.default_adapter
37
+ end
38
+ end
39
+
40
+ def fields
41
+ presignature["fields"] || {}
42
+ end
43
+
44
+ def file
45
+ config = FlyingSphinx::ConfigurationOptions.new input
46
+ writer = GZippedTar::Writer.new
47
+
48
+ writer.add "sphinx/raw.conf", config.raw
49
+ writer.add "sphinx/version.txt", config.version
50
+ writer.add "sphinx/extra.txt", config.settings["extra"]
51
+
52
+ config.settings["extra"].split(";").each do |key|
53
+ writer.add key, config.settings[key]
54
+ end unless config.settings["extra"].empty?
55
+
56
+ StringIO.new writer.output
57
+ end
58
+
59
+ def presignature
60
+ @presignature ||= api.get "/presignature"
61
+ end
62
+ end
@@ -1,4 +1,5 @@
1
1
  class FlyingSphinx::Controller
2
+ DEFAULT_TIMEOUT = 60
2
3
  @index_timeout = 60 * 60 * 3 # 3 hours
3
4
 
4
5
  # For backwards compatibility. These aren't actually used here.
@@ -17,12 +18,7 @@ class FlyingSphinx::Controller
17
18
  end
18
19
 
19
20
  def configure(file = nil)
20
- options = file.nil? ? FlyingSphinx::ConfigurationOptions.new.to_hash :
21
- {:configuration => {'sphinx' => file}, :sphinx_version => '2.0.6'}
22
-
23
- FlyingSphinx::Action.perform api.identifier do
24
- api.put 'configure', options
25
- end
21
+ run_action_with_path 'configure', file
26
22
  end
27
23
 
28
24
  def index(*indices)
@@ -31,24 +27,20 @@ class FlyingSphinx::Controller
31
27
  options[:indices] = indices.join(',')
32
28
 
33
29
  if async
34
- api.post 'indices/unique', options
30
+ send_action 'index', options.merge(:unique => 'true')
35
31
  else
36
32
  ::Delayed::Job.delete_all(
37
33
  "handler LIKE '--- !ruby/object:FlyingSphinx::%'"
38
34
  ) if defined?(::Delayed) && ::Delayed::Job.table_exists?
39
35
 
40
- FlyingSphinx::Action.perform api.identifier, self.class.index_timeout do
41
- api.post 'indices', options
42
- end
36
+ run_action 'index', self.class.index_timeout, options
43
37
  end
44
38
 
45
39
  true
46
40
  end
47
41
 
48
42
  def rebuild
49
- FlyingSphinx::Action.perform api.identifier, self.class.index_timeout do
50
- api.put 'rebuild', FlyingSphinx::ConfigurationOptions.new.to_hash
51
- end
43
+ run_action_with_path 'rebuild', nil, self.class.index_timeout
52
44
  end
53
45
 
54
46
  def regenerate(file = nil)
@@ -58,24 +50,15 @@ class FlyingSphinx::Controller
58
50
  end
59
51
 
60
52
  def reset(file = nil)
61
- options = file.nil? ? FlyingSphinx::ConfigurationOptions.new.to_hash :
62
- {:configuration => {'sphinx' => file}, :sphinx_version => '2.0.6'}
63
-
64
- FlyingSphinx::Action.perform api.identifier do
65
- api.put 'reset', options
66
- end
53
+ run_action_with_path 'reset', file
67
54
  end
68
55
 
69
56
  def restart
70
- FlyingSphinx::Action.perform api.identifier do
71
- api.post 'restart'
72
- end
57
+ run_action 'restart'
73
58
  end
74
59
 
75
60
  def rotate
76
- FlyingSphinx::Action.perform api.identifier do
77
- api.post 'rotate'
78
- end
61
+ run_action 'rotate'
79
62
  end
80
63
 
81
64
  def running?
@@ -87,14 +70,30 @@ class FlyingSphinx::Controller
87
70
  end
88
71
 
89
72
  def start(options = {})
90
- FlyingSphinx::Action.perform(api.identifier) { api.post 'start' }
73
+ run_action 'start'
91
74
  end
92
75
 
93
76
  def stop
94
- FlyingSphinx::Action.perform(api.identifier) { api.post 'stop' }
77
+ run_action 'stop'
95
78
  end
96
79
 
97
80
  private
98
81
 
99
82
  attr_reader :api
83
+
84
+ def run_action(action, timeout = DEFAULT_TIMEOUT, parameters = {})
85
+ FlyingSphinx::Action.perform api.identifier, timeout do
86
+ send_action action, parameters
87
+ end
88
+ end
89
+
90
+ def run_action_with_path(action, file = nil, timeout = DEFAULT_TIMEOUT)
91
+ path = FlyingSphinx::Configurer.new(api, file).call
92
+
93
+ run_action action, timeout, :path => path
94
+ end
95
+
96
+ def send_action(action, parameters = {})
97
+ api.post '/perform', parameters.merge(:action => action)
98
+ end
100
99
  end