cheap_skate 0.0.1 → 0.0.2

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.
data/bin/cheapskate ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+
4
+ require File.dirname(__FILE__)+'/../lib/cheap_skate/cli'
5
+ CheapSkate::CLI.new.run
@@ -1,4 +1,4 @@
1
- :default
1
+ :default:
2
2
  :prefix_path: /solr
3
3
  :ferret:
4
4
  :path: db/skate
@@ -61,8 +61,8 @@ END
61
61
  end
62
62
 
63
63
  before do
64
- if env[:prefix_path]
65
- request.path_info.sub!(/^#{env[:prefix_path]}/,'')
64
+ if options.prefix_path
65
+ request.path_info.sub!(/^#{options.prefix_path}/,'')
66
66
  end
67
67
  unless request.path_info[-1,1] == "/"
68
68
  request.path_info << "/"
@@ -0,0 +1,48 @@
1
+ require 'rake'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+ require File.dirname(__FILE__)+'/tasks'
5
+
6
+ module CheapSkate
7
+ class CLI < Rake::Application
8
+ def initialize
9
+ super
10
+ end
11
+ def load_rakefile
12
+ @name = 'cheapskate'
13
+
14
+ # Load the main warbler tasks
15
+ CheapSkate::Task.new
16
+
17
+ task :default => :help
18
+
19
+ desc "Create a new CheapSkate instance"
20
+ task :init => "cheapskate:init"
21
+
22
+ desc "Convert a Solr schema.xml to CheapSkate schema.yml"
23
+ task :convertschema => "cheapskate:convertschema"
24
+
25
+ end
26
+
27
+ # Loads the project Rakefile in a separate application
28
+ def load_project_rakefile
29
+ Rake.application = Rake::Application.new
30
+ Rake::Application::DEFAULT_RAKEFILES.each do |rf|
31
+ if File.exist?(rf)
32
+ load rf
33
+ break
34
+ end
35
+ end
36
+ Rake.application = self
37
+ end
38
+
39
+ # Run the application: The equivalent code for the +warble+ command
40
+ # is simply <tt>Warbler::Application.new.run</tt>.
41
+ def run
42
+ Rake.application = self
43
+ super
44
+ end
45
+ end
46
+
47
+ end
48
+
@@ -153,7 +153,7 @@ module CheapSkate
153
153
  bool.add_query(filtq, :must)
154
154
  else
155
155
  (idx, term) = fq.split(":")
156
- term.sub!(/^\"/,'').sub!(/\"$/,'')
156
+ term = term.sub(/^\"/,'').sub(/\"$/,'')
157
157
  bool.add_query(Ferret::Search::TermQuery.new(idx.to_sym, term), :must)
158
158
  end
159
159
  end
@@ -169,7 +169,46 @@ module CheapSkate
169
169
  end
170
170
 
171
171
  def parse_morelikethis_query(params)
172
+ q = case params["q"].class.name
173
+ when "Array" then params["q"].first
174
+ when "String" then params["q"]
175
+ else "*:*"
176
+ end
177
+ opts = {}
178
+ opts[:limit] = 1
179
+ if params['mlt.match.offset']
180
+ opts[:offset] = [*params['mlt.match.offset']].first.to_i
181
+ end
182
+ mlt = nil
183
+ self.search_each(q, opts) do |doc, score|
184
+ mlt = self[doc].load
185
+ end
186
+ bool = Ferret::Search::BooleanQuery.new
187
+ unless params['mlt.match.include'] && [*params['mlt.match.include']].first == "true"
188
+ b = Ferret::Search::BooleanQuery.new
189
+ bool.add_query(Ferret::Search::TermQuery.new(:id, mlt[:id]), :must_not)
190
+ end
191
+ mlt.each_pair do |key, val|
192
+
193
+ if val.is_a?(Array)
194
+ val.each do | v |
195
+ b = Ferret::Search::BooleanQuery.new
196
+ b.add_query(Ferret::Search::TermQuery.new(key, v))
197
+ bool << b
198
+ end
199
+ else
200
+ b = Ferret::Search::BooleanQuery.new
201
+ b.add_query(Ferret::Search::TermQuery.new(key, val))
202
+ bool << b
203
+ end
204
+ end
205
+ query = CheapSkate::Query.new
206
+
207
+ # No idea why this is necessary, but Ferret will ignore our boolean NOT otherwise
208
+ p = Ferret::QueryParser.new
209
+ query.query = p.parse(bool.to_s)
172
210
 
211
+ return query
173
212
  end
174
213
 
175
214
  def create_document(id=UUID.generate, boost=1.0)
@@ -263,7 +263,7 @@ end
263
263
  next
264
264
  end
265
265
  if @fields[i] == "id"
266
- doc[@index.schema.id_field] = field
266
+ doc[@index.schema.id_field] = field.strip
267
267
  else
268
268
  if @field_meta[@fields[i]] && @field_meta[@fields[i]]["split"] == "true"
269
269
  field.split(@field_meta[@fields[i]]["separator"]).each do |f|
@@ -1,227 +1,229 @@
1
1
  require 'rexml/document'
2
2
  require 'yaml'
3
- class CheapSkate::Schema
4
- include CheapSkate
5
- attr_reader :name, :fields, :config, :field_types, :id_field, :copy_fields, :dynamic_fields, :default_field, :default_operator
6
- def self.xml_to_yaml(xml)
7
- doc = REXML::Document.new xml
8
- y = {"schema"=>{"types"=>{}, "fields"=>{}}}
9
- y["schema"]["name"] = doc.root.attributes["name"]
10
- y["schema"]["version"] = doc.root.attributes["version"]
11
- doc.each_element("/schema/fields/field") do |field|
12
- f = {}
13
- field.attributes.each do |a,v|
14
- next if a == "name"
15
- f[a] = case v
16
- when "true" then true
17
- when "false" then false
18
- else v
3
+ module CheapSkate
4
+ class Schema
5
+ include CheapSkate
6
+ attr_reader :name, :fields, :config, :field_types, :id_field, :copy_fields, :dynamic_fields, :default_field, :default_operator
7
+ def self.xml_to_yaml(xml)
8
+ doc = REXML::Document.new xml
9
+ y = {"schema"=>{"types"=>{}, "fields"=>{}}}
10
+ y["schema"]["name"] = doc.root.attributes["name"]
11
+ y["schema"]["version"] = doc.root.attributes["version"]
12
+ doc.each_element("/schema/fields/field") do |field|
13
+ f = {}
14
+ field.attributes.each do |a,v|
15
+ next if a == "name"
16
+ f[a] = case v
17
+ when "true" then true
18
+ when "false" then false
19
+ else v
20
+ end
19
21
  end
22
+ y["schema"]["fields"][field.attributes['name']] = f
20
23
  end
21
- y["schema"]["fields"][field.attributes['name']] = f
22
- end
23
- doc.each_element("/schema/fields/dynamicField") do |dyn_field|
24
- f = {}
25
- dyn_field.attributes.each do |a,v|
26
- next if a == "name"
27
- f[a] = case v
28
- when "true" then true
29
- when "false" then false
30
- else v
24
+ doc.each_element("/schema/fields/dynamicField") do |dyn_field|
25
+ f = {}
26
+ dyn_field.attributes.each do |a,v|
27
+ next if a == "name"
28
+ f[a] = case v
29
+ when "true" then true
30
+ when "false" then false
31
+ else v
32
+ end
31
33
  end
32
- end
33
- y["schema"]["dynamic_fields"] ||= {}
34
- y["schema"]["dynamic_fields"][dyn_field.attributes['name']] = f
35
- end
36
- doc.each_element("/schema/types/fieldType") do |type|
37
- t = {}
38
- t[:type] = case type.attributes['class']
39
- when "solr.StrField" then :string
40
- when "solr.TextField" then :text
41
- when "solr.IntField" then :int
42
- when "solr.FloatField" then :float
43
- when "solr.BoolField" then :bool
44
- when "solr.DateField" then :date
45
- end
46
- if type.attributes['omitNorms'] && type.attributes['omitNorms'] == "true"
47
- t[:index] = :omit_norms
48
- end
49
- unless t[:type] == :text
50
- if t[:index] == :omit_norms
51
- t[:index] = :untokenized_omit_norms
52
- else
53
- t[:index] = :untokenized
34
+ y["schema"]["dynamic_fields"] ||= {}
35
+ y["schema"]["dynamic_fields"][dyn_field.attributes['name']] = f
36
+ end
37
+ doc.each_element("/schema/types/fieldType") do |type|
38
+ t = {}
39
+ t[:type] = case type.attributes['class']
40
+ when "solr.StrField" then :string
41
+ when "solr.TextField" then :text
42
+ when "solr.IntField" then :int
43
+ when "solr.FloatField" then :float
44
+ when "solr.BoolField" then :bool
45
+ when "solr.DateField" then :date
46
+ end
47
+ if type.attributes['omitNorms'] && type.attributes['omitNorms'] == "true"
48
+ t[:index] = :omit_norms
54
49
  end
50
+ unless t[:type] == :text
51
+ if t[:index] == :omit_norms
52
+ t[:index] = :untokenized_omit_norms
53
+ else
54
+ t[:index] = :untokenized
55
+ end
56
+ end
57
+ y["schema"]["types"][type.attributes['name']] = t
55
58
  end
56
- y["schema"]["types"][type.attributes['name']] = t
57
- end
58
- doc.each_element("/schema/types/fieldtype") do |type|
59
- t = {}
60
- t[:type] = case type.attributes['class']
61
- when "solr.StrField" then :string
62
- when "solr.TextField" then :text
63
- when "solr.IntField" then :int
64
- when "solr.FloatField" then :float
65
- when "solr.BoolField" then :bool
66
- when "solr.DateField" then :date
59
+ doc.each_element("/schema/types/fieldtype") do |type|
60
+ t = {}
61
+ t[:type] = case type.attributes['class']
62
+ when "solr.StrField" then :string
63
+ when "solr.TextField" then :text
64
+ when "solr.IntField" then :int
65
+ when "solr.FloatField" then :float
66
+ when "solr.BoolField" then :bool
67
+ when "solr.DateField" then :date
68
+ end
69
+ if type.attributes['omitNorms'] && type.attributes['omitNorms'] == "true"
70
+ t[:index] = :omit_norms
71
+ end
72
+ unless t[:type] == :text
73
+ if t[:index] == :omit_norms
74
+ t[:index] = :untokenized_omit_norms
75
+ else
76
+ t[:index] = :untokenized
77
+ end
78
+ end
79
+ y["schema"]["types"][type.attributes['name']] = t
80
+ end
81
+ if dflt = doc.elements['/schema/defaultSearchField']
82
+ y["schema"]["defaultSearchField"] = dflt.get_text.value if dflt.has_text?
67
83
  end
68
- if type.attributes['omitNorms'] && type.attributes['omitNorms'] == "true"
69
- t[:index] = :omit_norms
84
+ if uniq_key = doc.elements['/schema/uniqueKey']
85
+ y["schema"]["uniqueKey"] = uniq_key.get_text.value if uniq_key.has_text?
86
+ end
87
+ copy_fields = []
88
+ doc.each_element("/schema/copyField") do |copy|
89
+ copy_fields << {copy.attributes['source']=>copy.attributes['dest']}
70
90
  end
71
- unless t[:type] == :text
72
- if t[:index] == :omit_norms
73
- t[:index] = :untokenized_omit_norms
74
- else
75
- t[:index] = :untokenized
76
- end
91
+ unless copy_fields.empty?
92
+ y["schema"]["copyFields"] = copy_fields
77
93
  end
78
- y["schema"]["types"][type.attributes['name']] = t
79
- end
80
- if dflt = doc.elements['/schema/defaultSearchField']
81
- y["schema"]["defaultSearchField"] = dflt.get_text.value if dflt.has_text?
94
+ y.to_yaml
82
95
  end
83
- if uniq_key = doc.elements['/schema/uniqueKey']
84
- y["schema"]["uniqueKey"] = uniq_key.get_text.value if uniq_key.has_text?
85
- end
86
- copy_fields = []
87
- doc.each_element("/schema/copyField") do |copy|
88
- copy_fields << {copy.attributes['source']=>copy.attributes['dest']}
89
- end
90
- unless copy_fields.empty?
91
- y["schema"]["copyFields"] = copy_fields
92
- end
93
- y.to_yaml
94
- end
95
96
 
96
- def self.new_from_config(config_hash)
97
- schema = self.new
98
- schema.load_from_conf(config_hash)
99
- schema
100
- end
101
-
102
- def initialize
103
- @copy_fields = {}
104
- end
97
+ def self.new_from_config(config_hash)
98
+ schema = self.new
99
+ schema.load_from_conf(config_hash)
100
+ schema
101
+ end
105
102
 
106
- def load_from_conf(conf)
107
- @fields ={}
108
- @field_types ={}
109
- @name = conf['schema']['name']
110
- conf['schema']['fields'].keys.each do |field|
111
- @fields[field.to_sym] = {}
112
- fld = conf['schema']['fields'][field]
113
- @fields[field.to_sym][:field_type] = fld['type'].to_sym
114
- if fld['indexed'] == false
115
- @fields[field.to_sym][:index] = :no
116
- end
117
- if fld['stored'] == false
118
- @fields[field.to_sym][:store] = :no
119
- end
120
- @fields[field.to_sym][:multi_valued] = fld['multiValued']||false
103
+ def initialize
104
+ @copy_fields = {}
121
105
  end
122
- if conf['schema']['dynamic_fields']
123
- conf['schema']['dynamic_fields'].keys.each do |field|
124
- @dynamic_fields ||= {}
125
- @dynamic_fields[field.to_sym] = {}
126
- fld = conf['schema']['dynamic_fields'][field]
127
- @dynamic_fields[field.to_sym][:field_type] = fld['type'].to_sym
106
+
107
+ def load_from_conf(conf)
108
+ @fields ={}
109
+ @field_types ={}
110
+ @name = conf['schema']['name']
111
+ conf['schema']['fields'].keys.each do |field|
112
+ @fields[field.to_sym] = {}
113
+ fld = conf['schema']['fields'][field]
114
+ @fields[field.to_sym][:field_type] = fld['type'].to_sym
128
115
  if fld['indexed'] == false
129
- @dynamic_fields[field.to_sym][:index] = :no
116
+ @fields[field.to_sym][:index] = :no
130
117
  end
131
118
  if fld['stored'] == false
132
- @dynamic_fields[field.to_sym][:store] = :no
119
+ @fields[field.to_sym][:store] = :no
120
+ end
121
+ @fields[field.to_sym][:multi_valued] = fld['multiValued']||false
122
+ end
123
+ if conf['schema']['dynamic_fields']
124
+ conf['schema']['dynamic_fields'].keys.each do |field|
125
+ @dynamic_fields ||= {}
126
+ @dynamic_fields[field.to_sym] = {}
127
+ fld = conf['schema']['dynamic_fields'][field]
128
+ @dynamic_fields[field.to_sym][:field_type] = fld['type'].to_sym
129
+ if fld['indexed'] == false
130
+ @dynamic_fields[field.to_sym][:index] = :no
131
+ end
132
+ if fld['stored'] == false
133
+ @dynamic_fields[field.to_sym][:store] = :no
134
+ end
135
+ @dynamic_fields[field.to_sym][:multi_valued] = fld['multiValued']||false
133
136
  end
134
- @dynamic_fields[field.to_sym][:multi_valued] = fld['multiValued']||false
135
137
  end
136
- end
137
- conf['schema']['types'].keys.each do |type|
138
- @field_types[type.to_sym] = conf['schema']['types'][type]
139
- end
140
- conf['schema']['copyFields'].each do |copy|
141
- copy.each_pair do | orig, dest|
142
- @copy_fields[orig.to_sym] ||= []
143
- @copy_fields[orig.to_sym] << dest.to_sym
138
+ conf['schema']['types'].keys.each do |type|
139
+ @field_types[type.to_sym] = conf['schema']['types'][type]
144
140
  end
141
+ conf['schema']['copyFields'].each do |copy|
142
+ copy.each_pair do | orig, dest|
143
+ @copy_fields[orig.to_sym] ||= []
144
+ @copy_fields[orig.to_sym] << dest.to_sym
145
+ end
146
+ end
147
+ @id_field = (conf['schema']['uniqueKey'] || "id").to_sym
148
+ @default_field = (conf['schema']['defaultSearchField']||"*").to_sym
149
+ @default_operator = (conf['schema']['defaultOperator']||"OR")
145
150
  end
146
- @id_field = (conf['schema']['uniqueKey'] || "id").to_sym
147
- @default_field = (conf['schema']['defaultSearchField']||"*").to_sym
148
- @default_operator = (conf['schema']['defaultOperator']||"OR")
149
- end
150
151
 
151
- def typed_document(lazy_doc)
152
- doc = {}
153
- lazy_doc.fields.each do |field|
154
- [*lazy_doc[field]].each do |fld|
155
- if doc[field]
156
- doc[field] = [*doc[field]]
157
- doc[field] << type_field(field, fld)
158
- elsif multi_valued?(field)
159
- doc[field] = [type_field(field, fld)]
160
- else
161
- doc[field] = type_field(field, fld)
152
+ def typed_document(lazy_doc)
153
+ doc = {}
154
+ lazy_doc.fields.each do |field|
155
+ [*lazy_doc[field]].each do |fld|
156
+ if doc[field]
157
+ doc[field] = [*doc[field]]
158
+ doc[field] << type_field(field, fld)
159
+ elsif multi_valued?(field)
160
+ doc[field] = [type_field(field, fld)]
161
+ else
162
+ doc[field] = type_field(field, fld)
163
+ end
162
164
  end
163
165
  end
166
+ doc
164
167
  end
165
- doc
166
- end
167
168
 
168
- def multi_valued?(field)
169
- if @fields[field]
170
- return @fields[field][:multi_valued]
171
- else
172
- dyn_field = nil
173
- @dynamic_fields.keys.each do |dyn|
174
- if dyn =~ /^\*/
175
- r = Regexp.new(dyn.sub(/^\*/,".*"))
176
- elsif dyn =~ /\*$/
177
- r = Regexp.new(dyn.sub(/\*$/,".*"))
169
+ def multi_valued?(field)
170
+ if @fields[field]
171
+ return @fields[field][:multi_valued]
172
+ else
173
+ dyn_field = nil
174
+ @dynamic_fields.keys.each do |dyn|
175
+ if dyn =~ /^\*/
176
+ r = Regexp.new(dyn.sub(/^\*/,".*"))
177
+ elsif dyn =~ /\*$/
178
+ r = Regexp.new(dyn.sub(/\*$/,".*"))
179
+ end
180
+ if field =~ dyn
181
+ dyn_field = dyn
182
+ break
183
+ end
178
184
  end
179
- if field =~ dyn
180
- dyn_field = dyn
181
- break
182
- end
185
+ return dyn_field[:multi_valued] if dyn_field
183
186
  end
184
- return dyn_field[:multi_valued] if dyn_field
187
+ false
185
188
  end
186
- false
187
- end
188
189
 
189
- def type_field(field_name, value)
190
- return value.to_s unless @fields[field_name]
191
- val = case @field_types[@fields[field_name][:field_type]][:type]
192
- when :string then value.to_s
193
- when :text then value.to_s
194
- when :int then value.to_i
195
- when :float then value.to_f
196
- when :date then Date.parse(value)
197
- when :bool
198
- if value == "true"
199
- true
190
+ def type_field(field_name, value)
191
+ return value.to_s unless @fields[field_name]
192
+ val = case @field_types[@fields[field_name][:field_type]][:type]
193
+ when :string then value.to_s
194
+ when :text then value.to_s
195
+ when :int then value.to_i
196
+ when :float then value.to_f
197
+ when :date then Date.parse(value)
198
+ when :bool
199
+ if value == "true"
200
+ true
201
+ else
202
+ false
203
+ end
200
204
  else
201
- false
205
+ val.to_s
202
206
  end
203
- else
204
- val.to_s
207
+ val
205
208
  end
206
- val
207
- end
208
-
209
- def field_names
210
- return @fields.keys
211
- end
212
209
 
213
- def field_to_field_info(field_name)
214
- opts = {}
215
- if @fields[field_name][:index] == :no
216
- opts[:index] = :no
217
- opts[:term_vector] = :no
218
- elsif @field_types[@fields[field_name][:field_type]][:index]
219
- opts[:index] = @field_types[@fields[field_name][:field_type]][:index]
210
+ def field_names
211
+ return @fields.keys
220
212
  end
221
- if @fields[field_name][:stored] == :no
222
- opts[:store] = :no
213
+
214
+ def field_to_field_info(field_name)
215
+ opts = {}
216
+ if @fields[field_name][:index] == :no
217
+ opts[:index] = :no
218
+ opts[:term_vector] = :no
219
+ elsif @field_types[@fields[field_name][:field_type]][:index]
220
+ opts[:index] = @field_types[@fields[field_name][:field_type]][:index]
221
+ end
222
+ if @fields[field_name][:stored] == :no
223
+ opts[:store] = :no
224
+ end
225
+ Ferret::Index::FieldInfo.new(field_name, opts)
223
226
  end
224
- Ferret::Index::FieldInfo.new(field_name, opts)
225
- end
226
227
 
228
+ end
227
229
  end
@@ -0,0 +1,123 @@
1
+ require 'rake/tasklib'
2
+ require File.dirname(__FILE__)+'/schema'
3
+ module CheapSkate
4
+ class Task < Rake::TaskLib
5
+ attr_accessor :name
6
+ def initialize(name = :cheapskate)
7
+ @name = name
8
+
9
+ yield self if block_given?
10
+ define_tasks
11
+ end
12
+
13
+ private
14
+ def define_tasks
15
+ define_help_task
16
+ namespace name do
17
+ define_init_task
18
+ define_convertschema_task
19
+ end
20
+ end
21
+
22
+ def define_help_task
23
+ desc "Explains the available commands"
24
+ task "help" do
25
+ puts "Available commands:\n\n"
26
+ puts "\tcheapskate init [project_name] # creates a new CheapSkate instance"
27
+ puts "\tcheapskate convertschema xml=/path/to/schema.xml {yaml=/path/to/output/schema.yml} # converts a schema.xml to schema.yml"
28
+ end
29
+ end
30
+
31
+ def define_init_task
32
+
33
+ task :init do |t|
34
+ args = ARGV
35
+ raise ArgumentError, "Must supply an project name. Usage: cheapskate init {project_name}" if args.length < 2
36
+ raise ArgumentError, "Too many arguments supplied. Usage: cheapskate init {project_name}" if args.length > 2
37
+ raise ArgumentError, "First argument was not 'init' -- how did we get here?!" unless args.first == 'init'
38
+ cwd = Dir.getwd
39
+ project = args[1]
40
+ puts "Create new CheapSkate in #{cwd}/#{project}? [y/N]"
41
+ STDOUT.flush
42
+ input = STDIN.gets
43
+ input.chomp!
44
+ input = "N" if input !~ /^y$/i
45
+ if input == "N"
46
+ puts "Exiting."
47
+ exit
48
+ else
49
+ if exists = File.exists?("#{cwd}/#{project}")
50
+ puts "A directory already exists at #{cwd}/#{project}!\nExiting."
51
+ exit
52
+ else
53
+ puts "Creating CheapSkate root: #{cwd}/#{project}"
54
+ root = FileUtils.mkdir("#{cwd}/#{project}")
55
+ puts "Creating configuration directory: #{cwd}/#{project}/conf"
56
+ conf = FileUtils.mkdir("#{cwd}/#{project}/conf")
57
+ puts "Creating directory for the Ferret index: #{cwd}/#{project}/db"
58
+ db = FileUtils.mkdir("#{cwd}/#{project}/db")
59
+ puts "Creating log directory: #{cwd}/#{project}/log"
60
+ db = FileUtils.mkdir("#{cwd}/#{project}/log")
61
+ puts "Creating public directory: #{cwd}/#{project}/public"
62
+ db = FileUtils.mkdir("#{cwd}/#{project}/public")
63
+ config = {project.to_sym=>{:ferret=>{:path=>"db/skate"}, :facet_score_threshold=>0.0, :schema=>"conf/schema.yml"}}
64
+ puts "Writing default cheapskate.yml"
65
+ cs_yml = open("#{cwd}/#{project}/conf/cheapskate.yml", "w")
66
+ cs_yml << config.to_yaml
67
+ cs_yml.close
68
+ schema = {"schema"=>{"name"=>"example", "copyFields"=>[{"cat"=>"text"}, {"name"=>"text"}, {"manu"=>"text"}, {"features"=>"text"}, {"includes"=>"text"}, {"manu"=>"manu_exact"}], "fields"=>{"name"=>{"stored"=>true, "indexed"=>true, "type"=>"textgen"}, "cat"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"text_ws", "omitNorms"=>true}, "price"=>{"stored"=>true, "indexed"=>true, "type"=>"float"}, "popularity"=>{"stored"=>true, "indexed"=>true, "type"=>"int"}, "category"=>{"stored"=>true, "indexed"=>true, "type"=>"textgen"}, "includes"=>{"termOffsets"=>true, "stored"=>true, "indexed"=>true, "termVectors"=>true, "type"=>"text", "termPositions"=>true}, "title"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"text"}, "comments"=>{"stored"=>true, "indexed"=>true, "type"=>"text"}, "author"=>{"stored"=>true, "indexed"=>true, "type"=>"textgen"}, "content_type"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"string"}, "weight"=>{"stored"=>true, "indexed"=>true, "type"=>"float"}, "text"=>{"stored"=>false, "multiValued"=>true, "indexed"=>true, "type"=>"text"}, "id"=>{"required"=>true, "stored"=>true, "indexed"=>true, "type"=>"string"}, "subject"=>{"stored"=>true, "indexed"=>true, "type"=>"text"}, "text_rev"=>{"stored"=>false, "multiValued"=>true, "indexed"=>true, "type"=>"text_rev"}, "sku"=>{"stored"=>true, "indexed"=>true, "type"=>"textTight", "omitNorms"=>true}, "features"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"text"}, "links"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"string"}, "manu_exact"=>{"stored"=>false, "indexed"=>true, "type"=>"string"}, "inStock"=>{"stored"=>true, "indexed"=>true, "type"=>"boolean"}, "description"=>{"stored"=>true, "indexed"=>true, "type"=>"text"}, "alphaNameSort"=>{"stored"=>false, "indexed"=>true, "type"=>"alphaOnlySort"}, "manu"=>{"stored"=>true, "indexed"=>true, "type"=>"textgen", "omitNorms"=>true}, "last_modified"=>{"stored"=>true, "indexed"=>true, "type"=>"date"}, "payloads"=>{"stored"=>true, "indexed"=>true, "type"=>"payloads"}, "keywords"=>{"stored"=>true, "indexed"=>true, "type"=>"textgen"}}, "uniqueKey"=>"id", "version"=>"1.2", "types"=>{"pint"=>{:type=>:int, :index=>:untokenized_omit_norms}, "boolean"=>{:type=>:bool, :index=>:untokenized_omit_norms}, "tfloat"=>{:type=>nil, :index=>:untokenized_omit_norms}, "tdate"=>{:type=>nil, :index=>:untokenized_omit_norms}, "sfloat"=>{:type=>nil, :index=>:untokenized_omit_norms}, "phonetic"=>{:type=>:text}, "plong"=>{:type=>nil, :index=>:untokenized_omit_norms}, "pfloat"=>{:type=>:float, :index=>:untokenized_omit_norms}, "pdouble"=>{:type=>nil, :index=>:untokenized_omit_norms}, "binary"=>{:type=>nil, :index=>:untokenized}, "int"=>{:type=>nil, :index=>:untokenized_omit_norms}, "text"=>{:type=>:text}, "lowercase"=>{:type=>:text}, "date"=>{:type=>nil, :index=>:untokenized_omit_norms}, "sint"=>{:type=>nil, :index=>:untokenized_omit_norms}, "slong"=>{:type=>nil, :index=>:untokenized_omit_norms}, "text_rev"=>{:type=>:text}, "tint"=>{:type=>nil, :index=>:untokenized_omit_norms}, "tlong"=>{:type=>nil, :index=>:untokenized_omit_norms}, "tdouble"=>{:type=>nil, :index=>:untokenized_omit_norms}, "random"=>{:type=>nil, :index=>:untokenized}, "text_ws"=>{:type=>:text}, "textgen"=>{:type=>:text}, "string"=>{:type=>:string, :index=>:untokenized_omit_norms}, "double"=>{:type=>nil, :index=>:untokenized_omit_norms}, "pdate"=>{:type=>:date, :index=>:untokenized_omit_norms}, "sdouble"=>{:type=>nil, :index=>:untokenized_omit_norms}, "alphaOnlySort"=>{:type=>:text, :index=>:omit_norms}, "payloads"=>{:type=>:text}, "ignored"=>{:type=>:string, :index=>:untokenized}, "float"=>{:type=>nil, :index=>:untokenized_omit_norms}, "long"=>{:type=>nil, :index=>:untokenized_omit_norms}, "textTight"=>{:type=>:text}}, "dynamic_fields"=>{"*_tf"=>{"stored"=>true, "indexed"=>true, "type"=>"tfloat"}, "*_l"=>{"stored"=>true, "indexed"=>true, "type"=>"long"}, "*_b"=>{"stored"=>true, "indexed"=>true, "type"=>"boolean"}, "*_ti"=>{"stored"=>true, "indexed"=>true, "type"=>"tint"}, "random_*"=>{"type"=>"random"}, "*_d"=>{"stored"=>true, "indexed"=>true, "type"=>"double"}, "*_f"=>{"stored"=>true, "indexed"=>true, "type"=>"float"}, "*_tl"=>{"stored"=>true, "indexed"=>true, "type"=>"tlong"}, "*_tdt"=>{"stored"=>true, "indexed"=>true, "type"=>"tdate"}, "*_pi"=>{"stored"=>true, "indexed"=>true, "type"=>"pint"}, "*_s"=>{"stored"=>true, "indexed"=>true, "type"=>"string"}, "attr_*"=>{"stored"=>true, "multiValued"=>true, "indexed"=>true, "type"=>"textgen"}, "*_i"=>{"stored"=>true, "indexed"=>true, "type"=>"int"}, "*_t"=>{"stored"=>true, "indexed"=>true, "type"=>"text"}, "*_dt"=>{"stored"=>true, "indexed"=>true, "type"=>"date"}, "*_td"=>{"stored"=>true, "indexed"=>true, "type"=>"tdouble"}, "ignored_*"=>{"multiValued"=>true, "type"=>"ignored"}}, "defaultSearchField"=>"text"}}
69
+ puts "Writing default schema.yml"
70
+ s_yml = open("#{cwd}/#{project}/conf/schema.yml", "w")
71
+ s_yml << schema.to_yaml
72
+ s_yml.close
73
+ puts "Writing default rackup file at #{cwd}/#{project}/config.ru"
74
+ rackup = open("#{cwd}/#{project}/config.ru", "w")
75
+ rackup_body =<<END
76
+ require 'rubygems'
77
+ require 'sinatra'
78
+
79
+ root_dir = File.dirname(__FILE__)
80
+
81
+ set :environment, :production
82
+ set :configuration, root_dir+"/conf/cheapskate.yml"
83
+ set :site, :#{project}
84
+ set :root, root_dir
85
+
86
+ set :logging, false
87
+ disable :run
88
+
89
+ FileUtils.mkdir_p 'log' unless File.exists?('log')
90
+ log = File.new("log/\#{Sinatra::Application.site}.log", "a")
91
+ STDOUT.reopen(log)
92
+ STDERR.reopen(log)
93
+ require 'cheap_skate'
94
+ run CheapSkate::Application
95
+
96
+ END
97
+ rackup << rackup_body
98
+ rackup.close
99
+ end
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ def define_convertschema_task
106
+ desc "Parses a Solr schema.xml document and outputs a CheapSkate schema.yml. Needs the arguments xml=/path/to/schema.xml Defaults to ./conf/schema.yml, use the yaml= argument to specify the output."
107
+ task "convertschema" do
108
+ raise ArgumentError, "No schema.xml specified. Usage: cheapskate convertschema xml=/path/to/schema.xml" unless ENV['xml']
109
+ xml = open(ENV['xml'],'r')
110
+ yml = CheapSkate::Schema.xml_to_yaml(xml)
111
+ if ENV['yaml']
112
+ puts "Writing #{ENV['xml']} out to #{ENV['yaml']}."
113
+ outfile = open(ENV['yaml'],'w')
114
+ else
115
+ puts "Writing #{ENV['xml']} out to ./conf/schema.yml."
116
+ outfile = open('./conf/schema.yml','w')
117
+ end
118
+ outfile << yml.to_s
119
+ outfile.close
120
+ end
121
+ end
122
+ end
123
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ross Singer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-28 00:00:00 -04:00
17
+ date: 2010-06-01 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -91,8 +91,9 @@ dependencies:
91
91
  version_requirements: *id006
92
92
  description: A Solr-like interface for situations where running a Java application server is not an option (such as shared web hosting).
93
93
  email: rossfsinger@gmail.com
94
- executables: []
95
-
94
+ executables:
95
+ - cheapskate
96
+ - cheapskate
96
97
  extensions: []
97
98
 
98
99
  extra_rdoc_files:
@@ -104,9 +105,11 @@ files:
104
105
  - config.ru-dist
105
106
  - lib/cheap_skate.rb
106
107
  - lib/cheap_skate/application.rb
108
+ - lib/cheap_skate/cli.rb
107
109
  - lib/cheap_skate/index.rb
108
110
  - lib/cheap_skate/models.rb
109
111
  - lib/cheap_skate/schema.rb
112
+ - lib/cheap_skate/tasks.rb
110
113
  - LICENSE
111
114
  - README
112
115
  has_rdoc: true