togostanza 1.0.6 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc97dbc3b87d24a73ca0648a0e073e32e2bb2906
4
- data.tar.gz: ba821a103ec7b2d44e7c089535eb7ac929a8c636
3
+ metadata.gz: 2c89132e4c11121e7e06b99cdafbaff9afa086b0
4
+ data.tar.gz: 0e8c151c4ee36a69fca7c805081c688281382cad
5
5
  SHA512:
6
- metadata.gz: 8cf4e437c60074dae984afd871a7e715ab1418ea25e78e28f047121352abcdb0b32713d683b26eef24c432af8358699075edebff85c18a9e8218391c90ca3bee
7
- data.tar.gz: 743c1e1ebf7be8098faa23d1d020b415347406881e98268309a2ad7fc984a087f7784954d4d644a066c2b58a0de0b895195556e587737841c8ec43510af6e4dc
6
+ metadata.gz: a9421058afe1ba8dca550255ccd4d3db8e7b7a4fa1570de0831275582b2da4eba80b9f40e779ab16a5439aefb720e4887a5c8fe40c1e90e644e982837b4897d9
7
+ data.tar.gz: 5624ff06623b6f5d3ed83e611100fb5f37b00379850afb1b832d6be171775a93d2d23eaf6324afd8fd6fc63a838a6f0b6c94ab8e96fc65f7a2b3472fb72ba93f
@@ -44,5 +44,21 @@ module TogoStanza
44
44
 
45
45
  render :html, @stanza.help, layout_engine: :haml
46
46
  end
47
+
48
+ get '/:id/text_search' do |id|
49
+ @stanza = Stanza.find(id).new
50
+ stanza_uri = request.env['REQUEST_URI'].gsub(/\/text_search.*/, '')
51
+
52
+ begin
53
+ identifiers = @stanza.text_search(params[:q]).map {|param_hash|
54
+ parameters = Rack::Utils.build_query(param_hash)
55
+ "#{stanza_uri}?#{parameters}"
56
+ }
57
+
58
+ json enabled: true, count: identifiers.size, urls: identifiers
59
+ rescue NoSearchDeclarationError
60
+ json enabled: false, count: 0, urls: []
61
+ end
62
+ end
47
63
  end
48
64
  end
@@ -13,14 +13,23 @@ end
13
13
 
14
14
  module TogoStanza::Stanza
15
15
  autoload :ExpressionMap, 'togostanza/stanza/expression_map'
16
+ autoload :Grouping, 'togostanza/stanza/grouping'
16
17
  autoload :Markdown, 'togostanza/stanza/markdown'
17
18
  autoload :Querying, 'togostanza/stanza/querying'
18
- autoload :Grouping, 'togostanza/stanza/grouping'
19
+ autoload :TextSearch, 'togostanza/stanza/text_search'
20
+
21
+ class Context < Hashie::Mash
22
+ def respond_to_missing?(*)
23
+ # XXX It looks ugly, but we need use not pre-defined properties
24
+ true
25
+ end
26
+ end
19
27
 
20
28
  class Base
21
29
  extend ExpressionMap::Macro
22
30
  include Querying
23
31
  include Grouping
32
+ include TextSearch
24
33
 
25
34
  define_expression_map :properties
26
35
  define_expression_map :resources
@@ -51,7 +60,7 @@ module TogoStanza::Stanza
51
60
  attr_reader :params
52
61
 
53
62
  def context
54
- Hashie::Mash.new(properties.resolve_all_in_parallel(self, params))
63
+ Context.new(properties.resolve_all_in_parallel(self, params))
55
64
  end
56
65
 
57
66
  def resource(name)
@@ -0,0 +1,87 @@
1
+ require 'strscan'
2
+
3
+ module TogoStanza::Stanza
4
+ class SearchQuery
5
+ def initialize(query)
6
+ @raw = query
7
+ end
8
+
9
+ attr_reader :raw
10
+
11
+ def to_filter(method, var_name)
12
+ "FILTER (#{to_clause(method, var_name)})"
13
+ end
14
+
15
+ def tokens
16
+ @tokens ||= begin
17
+ scanner = StringScanner.new(@raw)
18
+ scanner.skip /\s+/
19
+
20
+ parse(scanner)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def to_clause(method, var_name)
27
+ case method.to_s
28
+ when 'regex', 'contains'
29
+ tokens.each_with_object('') {|token, acc|
30
+ case token
31
+ when :lparen
32
+ acc << '('
33
+ when :rparen
34
+ acc << ')'
35
+ when :or
36
+ acc << ' || '
37
+ when :and
38
+ acc << ' && '
39
+ else
40
+ acc << "#{method}(?#{var_name}, #{token.inspect})"
41
+ end
42
+ }
43
+ when 'bif_contains'
44
+ clause = tokens.each_with_object('') {|token, acc|
45
+ case token
46
+ when :lparen
47
+ acc << '('
48
+ when :rparen
49
+ acc << ')'
50
+ when :or
51
+ acc << ' OR '
52
+ when :and
53
+ acc << ' AND '
54
+ else
55
+ acc << token.inspect
56
+ end
57
+ }
58
+
59
+ "bif:contains(?#{var_name}, '#{clause}')"
60
+ else
61
+ raise ArgumentError, method
62
+ end
63
+ end
64
+
65
+ def parse(scanner, tokens = [])
66
+ scanner.skip /\s+\z/
67
+
68
+ return tokens if scanner.eos?
69
+
70
+ if scanner.scan(/"((?:[^\\"]|\\.)*)"/)
71
+ tokens << scanner[1].gsub(/\\(.)/, '\1')
72
+ elsif scanner.scan(/\(\s*/)
73
+ tokens << :lparen
74
+ elsif scanner.scan(/\s*\)/)
75
+ tokens << :rparen
76
+ elsif scanner.scan(/\s*OR\s*/)
77
+ tokens << :or
78
+ elsif scanner.scan(/\s*AND\s*|\s+/)
79
+ tokens << :and
80
+ else
81
+ tokens << scanner.scan(/\S+(?<!\))/)
82
+ end
83
+
84
+ parse(scanner, tokens)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,39 @@
1
+ require 'togostanza/stanza/search_query'
2
+
3
+ class TogoStanza::NoSearchDeclarationError < StandardError; end
4
+
5
+ module TogoStanza::Stanza
6
+ module TextSearch
7
+ extend ActiveSupport::Concern
8
+
9
+ def text_search_filter(var_name, query)
10
+ query.to_filter(TogoStanza.text_search_method, var_name)
11
+ end
12
+
13
+ def text_search(input)
14
+ raise TogoStanza::NoSearchDeclarationError unless self.class.method_defined?(:search_declarations)
15
+
16
+ query = SearchQuery.new(input)
17
+
18
+ return [] if query.tokens.empty?
19
+
20
+ search_declarations.each_value.flat_map {|block|
21
+ instance_exec(query, &block)
22
+ }
23
+ end
24
+
25
+ module ClassMethods
26
+ def search(symbol, &block)
27
+ unless method_defined?(:search_declarations)
28
+ # テキスト検索宣言の初期化
29
+ instance_eval do
30
+ class_attribute :search_declarations
31
+ self.search_declarations = {}
32
+ end
33
+ end
34
+
35
+ search_declarations[symbol] = block
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module TogoStanza
2
- VERSION = '1.0.6'
2
+ VERSION = '1.1.0'
3
3
  end
data/lib/togostanza.rb CHANGED
@@ -7,9 +7,21 @@ module TogoStanza
7
7
  autoload :Markdown, 'togostanza/markdown'
8
8
  autoload :Stanza, 'togostanza/stanza'
9
9
 
10
- def self.sprockets
11
- @sprockets ||= Sprockets::Environment.new.tap {|sprockets|
12
- sprockets.append_path File.expand_path('../../assets', __FILE__)
13
- }
10
+ class << self
11
+ attr_accessor :text_search_method
12
+
13
+ def configure
14
+ yield self
15
+ end
16
+
17
+ def sprockets
18
+ @sprockets ||= Sprockets::Environment.new.tap {|sprockets|
19
+ sprockets.append_path File.expand_path('../../assets', __FILE__)
20
+ }
21
+ end
22
+ end
23
+
24
+ configure do |config|
25
+ config.text_search_method = :regex
14
26
  end
15
27
  end
@@ -1 +1,3 @@
1
1
  <p>hello from {{name}}</p>
2
+
3
+ <p>nothing to display here: {{foo}}</p>
data/spec/spec_helper.rb CHANGED
@@ -1,11 +1,15 @@
1
1
  ENV['RACK_ENV'] ||= 'test'
2
2
 
3
- require_relative 'dummy/app'
4
-
3
+ require 'rspec/its'
5
4
  require 'capybara'
6
5
 
6
+ require_relative 'dummy/app'
7
+
7
8
  RSpec.configure do |config|
8
- config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.expect_with :rspec do |c|
10
+ c.syntax = %i(should expect)
11
+ end
12
+
9
13
  config.run_all_when_everything_filtered = true
10
14
  config.filter_run :focus
11
15
 
data/togostanza.gemspec CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency 'capybara'
34
34
  spec.add_development_dependency 'rake'
35
35
  spec.add_development_dependency 'rspec'
36
+ spec.add_development_dependency 'rspec-its'
36
37
 
37
38
  spec.required_ruby_version = '>= 1.9.3'
38
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: togostanza
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-20 00:00:00.000000000 Z
11
+ date: 2014-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -234,6 +234,20 @@ dependencies:
234
234
  - - ">="
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rspec-its
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
237
251
  description:
238
252
  email:
239
253
  - ursm@esm.co.jp
@@ -271,6 +285,8 @@ files:
271
285
  - lib/togostanza/stanza/grouping.rb
272
286
  - lib/togostanza/stanza/markdown.rb
273
287
  - lib/togostanza/stanza/querying.rb
288
+ - lib/togostanza/stanza/search_query.rb
289
+ - lib/togostanza/stanza/text_search.rb
274
290
  - lib/togostanza/version.rb
275
291
  - spec/dummy/app.rb
276
292
  - spec/dummy/bar_stanza/help.md
@@ -347,4 +363,3 @@ test_files:
347
363
  - spec/lib/togostanza/stanza/base_spec.rb
348
364
  - spec/lib/togostanza/stanza/grouping_spec.rb
349
365
  - spec/spec_helper.rb
350
- has_rdoc: