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 +4 -4
- data/lib/togostanza/application.rb +16 -0
- data/lib/togostanza/stanza/base.rb +11 -2
- data/lib/togostanza/stanza/search_query.rb +87 -0
- data/lib/togostanza/stanza/text_search.rb +39 -0
- data/lib/togostanza/version.rb +1 -1
- data/lib/togostanza.rb +16 -4
- data/spec/dummy/foo_stanza/template.hbs +2 -0
- data/spec/spec_helper.rb +7 -3
- data/togostanza.gemspec +1 -0
- metadata +18 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2c89132e4c11121e7e06b99cdafbaff9afa086b0
         | 
| 4 | 
            +
              data.tar.gz: 0e8c151c4ee36a69fca7c805081c688281382cad
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 : | 
| 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 | 
            -
                   | 
| 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
         | 
    
        data/lib/togostanza/version.rb
    CHANGED
    
    
    
        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 | 
            -
               | 
| 11 | 
            -
                 | 
| 12 | 
            -
             | 
| 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
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -1,11 +1,15 @@ | |
| 1 1 | 
             
            ENV['RACK_ENV'] ||= 'test'
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 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. | 
| 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 | 
| 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- | 
| 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: 
         |