flex 0.4.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +46 -7
  3. data/VERSION +1 -1
  4. data/flex.gemspec +13 -19
  5. data/lib/flex.rb +66 -392
  6. data/lib/flex/api_stubs.rb +1268 -0
  7. data/lib/flex/api_templates/cluster_api.yml +94 -0
  8. data/lib/flex/api_templates/core_api.yml +202 -0
  9. data/lib/flex/api_templates/indices_api.yml +304 -0
  10. data/lib/flex/class_proxy/base.rb +20 -6
  11. data/lib/flex/class_proxy/templates.rb +97 -0
  12. data/lib/flex/class_proxy/templates/doc.rb +91 -0
  13. data/lib/flex/class_proxy/templates/search.rb +72 -0
  14. data/lib/flex/configuration.rb +17 -49
  15. data/lib/flex/deprecation.rb +153 -0
  16. data/lib/flex/errors.rb +2 -1
  17. data/lib/flex/http_clients/base.rb +15 -0
  18. data/lib/flex/http_clients/loader.rb +51 -0
  19. data/lib/flex/http_clients/patron.rb +9 -7
  20. data/lib/flex/http_clients/rest_client.rb +6 -8
  21. data/lib/flex/logger.rb +24 -3
  22. data/lib/flex/prog_bar.rb +11 -6
  23. data/lib/flex/rails.rb +1 -13
  24. data/lib/flex/result.rb +8 -2
  25. data/lib/flex/result/document.rb +42 -13
  26. data/lib/flex/result/multi_get.rb +24 -0
  27. data/lib/flex/result/search.rb +1 -24
  28. data/lib/flex/struct/array.rb +25 -0
  29. data/lib/flex/struct/hash.rb +105 -0
  30. data/lib/flex/{result/collection.rb → struct/paginable.rb} +16 -9
  31. data/lib/flex/struct/prunable.rb +60 -0
  32. data/lib/flex/struct/symbolize.rb +27 -0
  33. data/lib/flex/tasks.rb +26 -86
  34. data/lib/flex/template.rb +60 -120
  35. data/lib/flex/template/common.rb +42 -0
  36. data/lib/flex/template/logger.rb +66 -0
  37. data/lib/flex/template/partial.rb +12 -15
  38. data/lib/flex/template/search.rb +6 -6
  39. data/lib/flex/template/slim_search.rb +1 -1
  40. data/lib/flex/template/tags.rb +19 -9
  41. data/lib/flex/templates.rb +20 -0
  42. data/lib/flex/utility_methods.rb +80 -89
  43. data/lib/flex/utils.rb +68 -25
  44. data/lib/flex/variables.rb +55 -4
  45. data/lib/tasks.rake +28 -0
  46. metadata +61 -85
  47. data/bin/flexes +0 -174
  48. data/lib/flex/api_methods.yml +0 -108
  49. data/lib/flex/class_proxy/loader.rb +0 -102
  50. data/lib/flex/class_proxy/model.rb +0 -45
  51. data/lib/flex/class_proxy/model_sync.rb +0 -23
  52. data/lib/flex/class_proxy/related_model.rb +0 -23
  53. data/lib/flex/instance_proxy/base.rb +0 -29
  54. data/lib/flex/instance_proxy/model.rb +0 -102
  55. data/lib/flex/instance_proxy/related_model.rb +0 -7
  56. data/lib/flex/loader.rb +0 -18
  57. data/lib/flex/manager.rb +0 -61
  58. data/lib/flex/model.rb +0 -24
  59. data/lib/flex/rails/engine.rb +0 -23
  60. data/lib/flex/rails/helper.rb +0 -16
  61. data/lib/flex/related_model.rb +0 -16
  62. data/lib/flex/result/indifferent_access.rb +0 -11
  63. data/lib/flex/result/source_document.rb +0 -63
  64. data/lib/flex/result/source_search.rb +0 -32
  65. data/lib/flex/structure/indifferent_access.rb +0 -44
  66. data/lib/flex/structure/mergeable.rb +0 -21
  67. data/lib/flex/template/base.rb +0 -41
  68. data/lib/flex/template/info.rb +0 -68
  69. data/lib/generators/flex/setup/setup_generator.rb +0 -48
  70. data/lib/generators/flex/setup/templates/flex_config.yml +0 -16
  71. data/lib/generators/flex/setup/templates/flex_dir/es.rb.erb +0 -18
  72. data/lib/generators/flex/setup/templates/flex_dir/es.yml.erb +0 -19
  73. data/lib/generators/flex/setup/templates/flex_dir/es_extender.rb.erb +0 -17
  74. data/lib/generators/flex/setup/templates/flex_initializer.rb.erb +0 -44
  75. data/lib/tasks/index.rake +0 -17
  76. data/test/flex.irt +0 -143
  77. data/test/flex/configuration.irt +0 -53
  78. data/test/irt_helper.rb +0 -12
@@ -1,18 +0,0 @@
1
- module Flex
2
- module Loader
3
-
4
- extend self
5
- attr_accessor :host_classes
6
- @host_classes = []
7
-
8
- def self.included(base)
9
- base.class_eval do
10
- Flex::Loader.host_classes |= [base]
11
- @flex ||= ClassProxy::Loader.new(base)
12
- def self.flex; @flex end
13
- end
14
- end
15
-
16
- end
17
- end
18
-
@@ -1,61 +0,0 @@
1
- module Flex
2
- module Manager
3
-
4
- extend self
5
-
6
- attr_accessor :parent_types
7
- @parent_types = []
8
-
9
- def init_models
10
- Configuration.flex_models.each {|m| eval"::#{m}" if m.is_a?(String) }
11
- end
12
-
13
- # arrays of all the types
14
- def types
15
- @types ||= Configuration.flex_models.map {|m| (m.is_a?(String) ? eval("::#{m}") : m).flex.type }.flatten
16
- end
17
-
18
- # sets the default parent/child mappings and merges with the config_file
19
- # returns the indices structure used for creating the indices
20
- def indices(file=Configuration.config_file)
21
- @indices ||= ( default = {}.extend Structure::Mergeable
22
- Configuration.flex_models.each do |m|
23
- m = eval"::#{m}" if m.is_a?(String)
24
- next unless m.flex.is_child?
25
- index = m.flex.index
26
- m.flex.parent_child_map.each do |parent, child|
27
- default.add index => {'mappings' => {child => {'_parent' => {'type' => parent }}}}
28
- end
29
- end
30
- hash = YAML.load(Utils.erb_process(file))
31
- hash.delete('ANCHORS')
32
- default.deep_merge(hash) )
33
- end
34
-
35
- # maps all the index/types to the ruby class
36
- def type_class_map
37
- @type_class_map ||= ( map = {}
38
- Configuration.flex_models.each do |m|
39
- m = eval("::#{m}") if m.is_a?(String)
40
- types = m.flex.type.is_a?(Array) ? m.flex.type : [m.flex.type]
41
- types.each do |t|
42
- map["#{m.flex.index}/#{t}"] = m
43
- end
44
- end
45
- map )
46
- end
47
-
48
- def class_name_to_type(class_name)
49
- type = class_name.tr(':', '_')
50
- type.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
51
- type.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
52
- type.downcase!
53
- type
54
- end
55
-
56
- def type_to_class_name(type)
57
- type.gsub(/__(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
58
- end
59
-
60
- end
61
- end
@@ -1,24 +0,0 @@
1
- module Flex
2
- module Model
3
-
4
- def self.included(base)
5
- base.class_eval do
6
- @flex ||= ClassProxy::Model.new(base)
7
- def self.flex; @flex end
8
- end
9
- end
10
-
11
- def flex
12
- @flex ||= InstanceProxy::Model.new(self)
13
- end
14
-
15
- def flex_source
16
- to_hash.reject {|k| k.to_s =~ /^_*id$/}.to_json
17
- end
18
-
19
- def flex_indexable?
20
- true
21
- end
22
-
23
- end
24
- end
@@ -1,23 +0,0 @@
1
- module Flex
2
- module Rails
3
- class Engine < ::Rails::Engine
4
-
5
- ActiveSupport.on_load(:before_configuration) do
6
- config.flex = Flex::Configuration
7
- config.flex.variables[:index] = [self.class.name.split('::').first.underscore, ::Rails.env].join('_')
8
- config.flex.config_file = ::Rails.root.join('config', 'flex.yml').to_s
9
- config.flex.flex_dir = ::Rails.root.join('app', 'flex').to_s
10
- config.flex.debug = ::Rails.env.development?
11
- end
12
-
13
- ActiveSupport.on_load(:after_initialize) do
14
- Helper.after_initialize
15
- end
16
-
17
- config.to_prepare do
18
- Flex.reload!
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,16 +0,0 @@
1
- module Flex
2
- module Rails
3
- module Helper
4
- extend self
5
-
6
- def after_initialize
7
- # use the same app logger
8
- Flex::Configuration.logger = ::Rails.logger
9
- # we need to reload the flex API methods with the new variables
10
- Flex.reload!
11
- Flex::Manager.init_models
12
- end
13
-
14
- end
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- module Flex
2
- module RelatedModel
3
-
4
- def self.included(base)
5
- base.class_eval do
6
- @flex ||= ClassProxy::RelatedModel.new(base)
7
- def self.flex; @flex end
8
- end
9
- end
10
-
11
- def flex
12
- @flex ||= InstanceProxy::RelatedModel.new(self)
13
- end
14
-
15
- end
16
- end
@@ -1,11 +0,0 @@
1
- module Flex
2
- module Result
3
- module IndifferentAccess
4
-
5
- def self.extended(result)
6
- result.extend Structure::IndifferentAccess
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,63 +0,0 @@
1
- module Flex
2
- class Result
3
-
4
- # adds sugar to documents with the following structure:
5
- #
6
- # {
7
- # "_index" : "twitter",
8
- # "_type" : "tweet",
9
- # "_id" : "1",
10
- # "_source" : {
11
- # "user" : "kimchy",
12
- # "postDate" : "2009-11-15T14:12:12",
13
- # "message" : "trying out Elastic Search"
14
- # }
15
- # }
16
-
17
- module SourceDocument
18
-
19
- # extend if result has a structure like a document
20
- def self.should_extend?(obj)
21
- %w[_index _type _id _source].all? {|k| obj.has_key?(k)}
22
- end
23
-
24
- # exposes _source: automatically supply object-like reader access
25
- # also expose meta fields like _id, _source, etc, also for methods without the leading '_'
26
- def method_missing(meth, *args, &block)
27
- case
28
- when meth.to_s =~ /^_/ && has_key?(meth.to_s) then self[meth.to_s]
29
- when self['_source'].has_key?(meth.to_s) then self['_source'][meth.to_s]
30
- when has_key?("_#{meth.to_s}") then self["_#{meth.to_s}"]
31
- else super
32
- end
33
- end
34
-
35
- # returns the _source hash with an added id (if missing))
36
- def to_attributes
37
- {'id' => _id}.merge(_source)
38
- end
39
-
40
- # creates an instance of a mapped or computed class, falling back to OpenStruct
41
- def to_mapped
42
- to(mapped_class || OpenStruct)
43
- end
44
-
45
- # experimental: creates an instance of klass out of to_attributes
46
- # we should probably reset the id to the original document _id
47
- # but be sure the record is read-only
48
- def to(klass)
49
- obj = klass.new(to_attributes)
50
- case
51
- when defined?(ActiveRecord::Base) && obj.is_a?(ActiveRecord::Base)
52
- obj.readonly!
53
- when defined?(Mongoid::Document) && obj.is_a?(Mongoid::Document)
54
- # TODO: make it readonly
55
- when obj.is_a?(OpenStruct)
56
- # TODO: anythig to extend?
57
- end
58
- obj
59
- end
60
-
61
- end
62
- end
63
- end
@@ -1,32 +0,0 @@
1
- module Flex
2
- class Result
3
- module SourceSearch
4
-
5
- # extend if result comes from a search url and does not contain an empty fields param (no _source))
6
- def self.should_extend?(result)
7
- result.response.url =~ /\b_m?search\b/ &&
8
- !result['hits']['hits'].empty? && result['hits']['hits'].first.has_key?('_source')
9
- end
10
-
11
- # extend the hits results on extended
12
- def self.extended(result)
13
- result['hits']['hits'].each { |h| h.extend(SourceDocument) }
14
- end
15
-
16
- # experimental
17
- # returns an array of document mapped objects
18
- def mapped_collection
19
- @mapped_collection ||= begin
20
- docs = self['hits']['hits'].map do |h|
21
- raise NameError, "no '_source' found in hit #{h.inspect} " \
22
- unless h.respond_to(:to_mapped)
23
- h.to_mapped
24
- end
25
- docs.extend Collection
26
- docs.setup(self['hits']['total'], variables)
27
- end
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,44 +0,0 @@
1
- module Flex
2
- module Structure
3
- # allows to use both Symbol or String keys to access the same values in a Hash
4
- module IndifferentAccess
5
-
6
- def [](k)
7
- get_value(k)
8
- end
9
-
10
- def []=(k,v)
11
- # default to_s for storing new keys
12
- has_key?(k) ? super : super(k.to_s, v)
13
- end
14
-
15
- def to_hash
16
- self
17
- end
18
-
19
- private
20
-
21
- def get_value(k)
22
- val = fetch_val(k)
23
- case val
24
- when Hash
25
- val.extend IndifferentAccess
26
- when Array
27
- val.each {|v| v.extend IndifferentAccess if v.is_a?(Hash)}
28
- end
29
- val
30
- end
31
-
32
- def fetch_val(k)
33
- v = fetch(k, nil)
34
- return v unless v.nil?
35
- if k.is_a?(String)
36
- v = fetch(k.to_sym, nil)
37
- return v unless v.nil?
38
- end
39
- fetch(k.to_s, nil) if k.is_a?(Symbol)
40
- end
41
-
42
- end
43
- end
44
- end
@@ -1,21 +0,0 @@
1
- module Flex
2
- module Structure
3
- # allows deep merge between Hashes
4
- module Mergeable
5
-
6
- def deep_merge(*hashes)
7
- Utils.deep_merge_hashes(self, *hashes)
8
- end
9
-
10
- def deep_merge!(*hashes)
11
- replace deep_merge(*hashes)
12
- end
13
- alias_method :add, :deep_merge!
14
-
15
- def deep_dup
16
- Marshal.load(Marshal.dump(self))
17
- end
18
-
19
- end
20
- end
21
- end
@@ -1,41 +0,0 @@
1
- module Flex
2
- class Template
3
-
4
- module PrunableObject end
5
-
6
- module Base
7
-
8
- def process_vars(vars)
9
- missing = @tags - vars.keys
10
- raise ArgumentError, "required variables #{missing.inspect} missing." \
11
- unless missing.empty?
12
- @partials.each do |k|
13
- raise MissingPartialError, "undefined #{k} partial template" \
14
- unless @host_flex.partials.has_key?(k)
15
- next if vars[k].nil?
16
- vars[k] = [vars[k]] unless vars[k].is_a?(Array)
17
- vars[k] = vars[k].map {|v| @host_flex.partials[k].interpolate(@variables.deep_dup, v)}
18
- end
19
- vars[:index] = vars[:index].join(',') if vars[:index].is_a?(Array)
20
- vars[:type] = vars[:type].join(',') if vars[:type].is_a?(Array)
21
- if vars[:page]
22
- vars[:params] ||= {}
23
- vars[:params][:size] ||= vars[:size] || 10
24
- page = vars[:page].to_i
25
- page = 1 unless page > 0
26
- vars[:params][:from] = ((page - 1) * vars[:params][:size]).ceil
27
- end
28
- vars
29
- end
30
-
31
- # extend obj with PrunableObject if it is nil or it is an empty Array or Hash
32
- # called from stringified
33
- def prunable(name, vars)
34
- obj = vars[name]
35
- return obj if vars[:no_pruning].include?(name)
36
- (obj.nil? || obj == [] || obj == {}) ? obj.extend(PrunableObject) : obj
37
- end
38
-
39
- end
40
- end
41
- end
@@ -1,68 +0,0 @@
1
- module Flex
2
- class Template
3
- module Info
4
-
5
- def info(*names)
6
- names = templates.keys if names.empty?
7
- info = "\n"
8
- names.each do |name|
9
- next unless templates.include?(name)
10
- block = ''
11
- temp = templates[name]
12
- meth_call = [host_class, name].join('.')
13
- block << <<-meth_call
14
- ########## #{meth_call} ##########
15
-
16
- #{'-' * temp.class.to_s.length}
17
- #{temp.class}
18
- #{temp.to_flex(name)}
19
- meth_call
20
- temp.partials.each do |par_name|
21
- par = partials[par_name]
22
- block << <<-partial
23
- #{'-' * par.class.to_s.length}
24
- #{par.class}
25
- #{par.to_flex(par_name)}
26
- partial
27
- end
28
- block << "\nUsage:\n"
29
- block << usage(meth_call, temp)
30
- block << "\n "
31
- info << block.split("\n").map{|l| '# ' + l}.join("\n")
32
- info << <<-meth
33
-
34
- def #{meth_call}(vars={})
35
- ## this is a stub, used for reference
36
- end
37
-
38
-
39
- meth
40
- end
41
- info
42
- end
43
-
44
- private
45
-
46
- def usage(meth_call, temp)
47
- all_tags = temp.tags + temp.partials
48
- lines = all_tags.map do |t|
49
- comments = 'partial' if t.to_s.match(/^_/)
50
- ['', t.to_s] + (temp.variables.has_key?(t) ? ["#{temp.variables[t].inspect},", comments_to_s(comments)] \
51
- : ["#{t},", comments_to_s(comments, 'required')])
52
- end
53
- lines.sort! { |a,b| b[3] <=> a[3] }
54
- lines.first[0] = meth_call
55
- lines.last[2].chop!
56
- max = lines.transpose.map { |c| c.map(&:length).max }
57
- lines.map { |line| "%-#{max[0]}s :%-#{max[1]}s => %-#{max[2]}s %s" % line }.join("\n")
58
- end
59
-
60
- def comments_to_s(*comments)
61
- comments = comments.compact
62
- return '' if comments == []
63
- "# #{comments.join(' ')}"
64
- end
65
-
66
- end
67
- end
68
- end