flying-sphinx 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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