cheap_skate 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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