flex 0.4.2 → 1.0.1

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.
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