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 +5 -0
- data/conf/cheapskate.yml-dist +1 -1
- data/lib/cheap_skate/application.rb +2 -2
- data/lib/cheap_skate/cli.rb +48 -0
- data/lib/cheap_skate/index.rb +40 -1
- data/lib/cheap_skate/models.rb +1 -1
- data/lib/cheap_skate/schema.rb +191 -189
- data/lib/cheap_skate/tasks.rb +123 -0
- metadata +8 -5
data/bin/cheapskate
ADDED
data/conf/cheapskate.yml-dist
CHANGED
@@ -61,8 +61,8 @@ END
|
|
61
61
|
end
|
62
62
|
|
63
63
|
before do
|
64
|
-
if
|
65
|
-
request.path_info.sub!(/^#{
|
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
|
+
|
data/lib/cheap_skate/index.rb
CHANGED
@@ -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
|
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)
|
data/lib/cheap_skate/models.rb
CHANGED
@@ -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|
|
data/lib/cheap_skate/schema.rb
CHANGED
@@ -1,227 +1,229 @@
|
|
1
1
|
require 'rexml/document'
|
2
2
|
require 'yaml'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
69
|
-
|
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
|
72
|
-
|
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
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
107
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
@
|
116
|
+
@fields[field.to_sym][:index] = :no
|
130
117
|
end
|
131
118
|
if fld['stored'] == false
|
132
|
-
@
|
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
|
-
|
137
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
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
|
-
|
180
|
-
dyn_field = dyn
|
181
|
-
break
|
182
|
-
end
|
185
|
+
return dyn_field[:multi_valued] if dyn_field
|
183
186
|
end
|
184
|
-
|
187
|
+
false
|
185
188
|
end
|
186
|
-
false
|
187
|
-
end
|
188
189
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
205
|
+
val.to_s
|
202
206
|
end
|
203
|
-
|
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
|
-
|
214
|
-
|
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
|
-
|
222
|
-
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
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
|