picky-generators 2.0.0.pre1 → 2.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/prototypes/client/sinatra/Gemfile +1 -1
- data/prototypes/client/sinatra/app.rb +20 -17
- data/prototypes/client/sinatra/book.rb +1 -1
- data/prototypes/client/sinatra/images/picky.png +0 -0
- data/prototypes/client/sinatra/javascripts/picky.min.js +2 -2
- data/prototypes/client/sinatra/stylesheets/application.css +1 -1
- data/prototypes/client/sinatra/views/search.haml +2 -1
- data/prototypes/server/shared_unicorn/Gemfile +1 -1
- data/prototypes/server/unicorn/app/application.rb +13 -24
- metadata +4 -4
@@ -2,21 +2,22 @@ require 'rubygems'
|
|
2
2
|
require 'bundler'
|
3
3
|
Bundler.require
|
4
4
|
|
5
|
-
#
|
5
|
+
# Sinatra settings.
|
6
6
|
#
|
7
|
-
|
7
|
+
set :static, true
|
8
|
+
set :public, File.dirname(__FILE__)
|
9
|
+
set :views, File.expand_path('views', File.dirname(__FILE__))
|
10
|
+
set :haml, :format => :html5
|
8
11
|
|
9
|
-
|
12
|
+
# Load the simplified "model".
|
13
|
+
#
|
14
|
+
require File.expand_path 'book', File.dirname(__FILE__)
|
10
15
|
|
11
16
|
# Sets up a search instance to the server.
|
12
17
|
#
|
13
18
|
BookSearch = Picky::Client.new :host => 'localhost', :port => 8080, :path => '/books'
|
14
19
|
|
15
|
-
|
16
|
-
set :public, File.dirname(__FILE__)
|
17
|
-
set :views, File.expand_path('views', File.dirname(__FILE__))
|
18
|
-
|
19
|
-
# Root, the search interface.
|
20
|
+
# Root, the search page.
|
20
21
|
#
|
21
22
|
get '/' do
|
22
23
|
@query = params[:q]
|
@@ -24,12 +25,8 @@ get '/' do
|
|
24
25
|
haml :'/search'
|
25
26
|
end
|
26
27
|
|
27
|
-
#
|
28
|
+
# Renders the results into the json.
|
28
29
|
#
|
29
|
-
get '/configure' do
|
30
|
-
haml :'/configure'
|
31
|
-
end
|
32
|
-
|
33
30
|
# You get the ids from the picky server and then
|
34
31
|
# populate the result with rendered models.
|
35
32
|
#
|
@@ -37,21 +34,21 @@ get '/search/full' do
|
|
37
34
|
results = BookSearch.search params[:query], :ids => params[:ids], :offset => params[:offset]
|
38
35
|
results.extend Picky::Convenience
|
39
36
|
results.populate_with Book do |book|
|
40
|
-
book.
|
37
|
+
book.render
|
41
38
|
end
|
42
39
|
|
43
40
|
#
|
44
|
-
# Or use:
|
41
|
+
# Or, to populate with the model instances, use:
|
45
42
|
# results.populate_with Book
|
46
43
|
#
|
47
|
-
# Then:
|
44
|
+
# Then to render:
|
48
45
|
# rendered_entries = results.entries.map do |book| (render each book here) end
|
49
46
|
#
|
50
47
|
|
51
48
|
ActiveSupport::JSON.encode results
|
52
49
|
end
|
53
50
|
|
54
|
-
#
|
51
|
+
# Updates the search count while the user is typing.
|
55
52
|
#
|
56
53
|
# We don't parse/reencode the returned json string using search_unparsed.
|
57
54
|
#
|
@@ -59,6 +56,12 @@ get '/search/live' do
|
|
59
56
|
BookSearch.search_unparsed params[:query], :ids => params[:ids], :offset => params[:offset]
|
60
57
|
end
|
61
58
|
|
59
|
+
# Configure. The configuration info page.
|
60
|
+
#
|
61
|
+
get '/configure' do
|
62
|
+
haml :'/configure'
|
63
|
+
end
|
64
|
+
|
62
65
|
helpers do
|
63
66
|
|
64
67
|
def js path
|
Binary file
|
@@ -6,8 +6,8 @@ this.text=o;var q=function(h){n.text(h);h>0&&h<=5&&n.fadeTo("fast",0.5).fadeTo("
|
|
6
6
|
d.focus()}else{k.remove();p.render(h);$("body").animate({scrollTop:$("#picky div.results div.header:last").position().top-12},500)}};this.liveResultsCallback=function(h){v(w(h));q(h.total)};this.allocationChosen=function(h){h=h.data.query;d.val(h);c.allocationChosen(h)};this.addinationClicked=function(h){c.addinationClicked(o(),h)};(function(){d.keyup(function(h){if(o()==""){f();c.searchTextCleared()}else{c.searchTextEntered(o(),h);a()}});n.click(function(){o()==""||c.searchButtonClicked(o())});m.click(function(){o()==
|
7
7
|
""||c.searchButtonClicked(o())});e.click(function(){f("");c.clearButtonClicked();d.focus()})})();d.focus()};var PickyBackend=function(c){var i=function(g,d,e,m){var n=m||{};n=$.extend({query:g,offset:e},m);$.getJSON(c,n,function(s){d&&d(new PickyData(s))})};this.search=function(g,d,e,m,n){i(g,function(s){d&&d(n,s)},e,m)}},LiveBackend=function(c){var i=new PickyBackend(c);this.search=function(g,d,e,m,n){n=n||{};latestRequestTimestamp=new Date;n.live=latestRequestTimestamp;m=$.extend({ids:0},m);i.search(g,function(s,u){if(!s.live||s.live==latestRequestTimestamp)d&&d(u)},e,m,n)}},FullBackend=function(c){var i=
|
8
8
|
new PickyBackend(c);this.search=function(g,d,e,m,n){n=n||{};latestRequestTimestamp=new Date;n.full=latestRequestTimestamp;m=$.extend({ids:20},m);i.search(g,function(s,u){if(!s.full||s.full==latestRequestTimestamp)d&&d(u)},e,m,n)}};var PickyController=function(c){var i=new PickyView(this,c),g=c.backends,d=c.before||function(){},e=c.success||function(){},m=c.after||function(){},n=function(a){return(a=a&&a.match(/q=([^&]+)/))&&unescape(a[1]||"")};this.extractQuery=n;var s=function(){var a=window.History&&window.History.getState();return n(a&&a.url)};this.lastQuery=s;var u=function(a,b){a=e(a,b)||a;i.liveResultsCallback(a);m(a,b)},j,k=function(){var a=i.text();d({});var b=g.live;b&&b.search(a,u,0,void 0);clearInterval(j)};j=setInterval(k,
|
9
|
-
180);clearInterval(j);var r=function(a,b){a=e(a,b)||a;i.fullResultsCallback(a);m(a,b)},p=function(a,b,f){f=f||{};b=b||0;clearInterval(j);if(a!=s()){var o="?q="+a;window.History&&window.History.getState()&&window.History.pushState&&window.History.pushState(null,null,o)}f=d(f,a,b)||f;(o=g.full)&&o.search(a,r,b,f)};this.insert=function(a,b){i.insert(a);b&&p(a)};this.clearButtonClicked=function(){clearInterval(j)};this.searchTextCleared=function(){clearInterval(j)};this.searchTextEntered=
|
10
|
-
[0,8,13,32,46,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90])>-1)if(b.keyCode==13)p(a);else{clearInterval(j);j=setInterval(k,180)}};this.searchButtonClicked=function(a){p(a)};this.allocationChosen=function(a){p(a)};this.addinationClicked=function(a,b){p(a,b.data.offset)}};var Localization={},PickyClient=function(c){Localization.qualifiers=c.qualifiers||{};Localization.explanations=c.explanations||{};Localization.choices=c.choices||{};Localization.explanation_delimiters={de:"und",fr:"et",it:"e",en:"and",ch:"und"};var i=c.backends;if(i){i.live||alert("Both a full and live backend must be provided.");i.full||alert("Both a full and live backend must be provided.")}else c.backends={live:c.live&&new LiveBackend(c.live)||alert("A live backend path must be provided."),full:c.full&&
|
9
|
+
180);clearInterval(j);var r=function(a,b){a=e(a,b)||a;i.fullResultsCallback(a);m(a,b)},p=function(a,b,f){f=f||{};b=b||0;clearInterval(j);if(a!=s()){var o="?q="+escape(a).replace(/\*/g,"%2A");window.History&&window.History.getState()&&window.History.pushState&&window.History.pushState(null,null,o)}f=d(f,a,b)||f;(o=g.full)&&o.search(a,r,b,f)};this.insert=function(a,b){i.insert(a);b&&p(a)};this.clearButtonClicked=function(){clearInterval(j)};this.searchTextCleared=function(){clearInterval(j)};this.searchTextEntered=
|
10
|
+
function(a,b){if($.inArray(b.keyCode,[0,8,13,32,46,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90])>-1)if(b.keyCode==13)p(a);else{clearInterval(j);j=setInterval(k,180)}};this.searchButtonClicked=function(a){p(a)};this.allocationChosen=function(a){p(a)};this.addinationClicked=function(a,b){p(a,b.data.offset)}};var Localization={},PickyClient=function(c){Localization.qualifiers=c.qualifiers||{};Localization.explanations=c.explanations||{};Localization.choices=c.choices||{};Localization.explanation_delimiters={de:"und",fr:"et",it:"e",en:"and",ch:"und"};var i=c.backends;if(i){i.live||alert("Both a full and live backend must be provided.");i.full||alert("Both a full and live backend must be provided.")}else c.backends={live:c.live&&new LiveBackend(c.live)||alert("A live backend path must be provided."),full:c.full&&
|
11
11
|
new FullBackend(c.full)||alert("A live backend path must be provided.")};var g=c.controller&&new c.controller(c)||new PickyController(c);var d=this.insert=function(e,m){g.insert(e,m||true)};this.insertFromURL=function(e){if(e&&e!="")d(e);else(e=g.lastQuery())&&d(e)};window.History&&window.History.Adapter.bind(window,"statechange",function(){var e=window.History.getState();(e=g.extractQuery(e.url))&&d(e)})};var PickyAddination=function(c,i){this.remove=function(){i.find(".addination").remove()};this.render=function(g){var d=g.total,e;e=g.offset+20+0;var m=e+20;g=g.total;if(g<m)m=g;e={offset:e,start:e+1,end:m};if(e.offset<d){d=$("<div class='addination'>"+t("results.addination.more")+"</div>");d.bind("click",{offset:e.offset},c.addinationClicked);return d}else return""}};var PickyResultsRenderer=function(c,i){var g=i.wrapResults||'<ol class="results"></ol>',d=["street_number","zipcode"],e=function(j){var k=j[j.length-1];j=j.slice(0,j.length-1);if(j==[])j=[j];if(!d.include(k[0]))if(k[1].match(/[^\*~]$/))k[1]+="*";j.push(k);return j},m=function(j){for(var k=Localization.explanations&&Localization.explanations[PickyI18n.locale]||{},r=[],p,a=0,b=j.length;a<b;a++){p=j[a];var f=p[0];f=k[f]||f;r.push([f,p[1]])}return r},n=function(j,k){return[j.replace(/([\w\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00e9\u00e8\u00e0]+)/,
|
12
12
|
"<strong>$1</strong>"),k].join(" ")},s=function(j,k){var r=Localization.explanation_delimiters[PickyI18n.locale],p=m(e(k)),a="",b=[];p=$.map(p,function(f){var o=f[0];f=f[1];if(a==""||o==a){b.push(f);a=o}else{var q=n(a,b.join(" "));b=[];b.push(f);a=o;return q}});p.push(n(a,b.join(" ")));p=p.join(" "+r+" ");return'<span class="explanation">'+j+" "+p+"</span>"},u=function(j,k){var r='<div class="header">';r+=s(k.type,k.combination);if(j.offset>0)r+='<div class="tothetop"><a href="#" onclick="javascript:$(\'body\').animate({scrollTop: 0}, 500);">↑</a></div>';
|
13
13
|
return r};this.render=function(j){var k=$("#picky div.results");j.allocations.each(function(r,p){k.append(u(j,p)).append(p.entries.join("")).append(c.render(j));k.children("li").wrapAll(g)})}};function AllocationRenderer(c,i){function g(a){var b={},f={},o=[],q;q=0;for(l=a.length;q<l;q++){var w=a[q][0];if(w in b){b[w]=b[w]+" "+a[q][1];o.push(q)}else{b[w]=a[q][1];f[q]=w}}for(q in f)a[q][1]=b[f[q]];for(q=o.length-1;q>=0;q--)a.remove(o[q]);return a}function d(a){return $.map(a,function(b,f){return"%"+(f+1)+"$s"}).join(" ")}function e(a){if(a.length==0)return"";var b=a=g(a);b.sort(function(x,y){return x[0]<y[0]?-1:1});for(var f=[],o=0,q=b.length;o<q;o++)f.push(b[o][0]);var w=f.length==1,v=r[f]||
|
@@ -3,44 +3,33 @@
|
|
3
3
|
# TODO Adapt the generated example
|
4
4
|
# (a library books finder) to what you need.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
# Ask me or the google group if you have questions or specific requests.
|
6
|
+
# Questions? Mail me, IRC #picky, the google group, http://github.com/floere/picky/wiki.
|
8
7
|
#
|
9
8
|
class PickySearch < Application
|
10
9
|
|
11
|
-
#
|
10
|
+
# How text is indexed.
|
12
11
|
#
|
13
12
|
default_indexing removes_characters: /[^a-zA-Z0-9\s\/\-\"\&\.]/,
|
14
13
|
stopwords: /\b(and|the|of|it|in|for)\b/,
|
15
14
|
splits_text_on: /[\s\/\-\"\&\.]/
|
16
15
|
|
17
|
-
#
|
16
|
+
# How query text is preprocessed.
|
18
17
|
#
|
19
18
|
default_querying removes_characters: /[^a-zA-Z0-9\s\/\-\,\&\"\~\*\:]/, # Picky needs control chars *"~: to pass through.
|
20
19
|
stopwords: /\b(and|the|of|it|in|for)\b/,
|
21
20
|
splits_text_on: /[\s\/\-\,\&]+/,
|
22
|
-
|
23
|
-
maximum_tokens: 5, # Amount of tokens passing into a query (5 = default).
|
21
|
+
maximum_tokens: 5, # Amount of tokens used in a search (5 = default).
|
24
22
|
substitutes_characters_with: CharacterSubstituters::WestEuropean.new # Normalizes special user input, Ä -> Ae, ñ -> n etc.
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
books_index.define_category :author,
|
35
|
-
partial: Partial::Substring.new(from: 1)
|
36
|
-
books_index.define_category :year,
|
37
|
-
partial: Partial::None.new # Partial substring searching on the year does not make
|
38
|
-
# much sense, neither does similarity.
|
39
|
-
|
40
|
-
options = { :weights => { [:title, :author] => +3, [:title] => +1 } } # +/- points for combinations.
|
41
|
-
|
42
|
-
route %r{\A/books\Z} => Search.new(books_index, options)
|
24
|
+
library_src = Sources::CSV.new :title, :author, :year, file: 'app/library.csv'
|
25
|
+
books_index = Index::Memory.new :books, library_src do
|
26
|
+
category :title,
|
27
|
+
similarity: Similarity::Phonetic.new(3), # Default is no similarity.
|
28
|
+
partial: Partial::Substring.new(from: 1) # Default is from: -3.
|
29
|
+
category :author, partial: Partial::Substring.new(from: 1)
|
30
|
+
category :year, partial: Partial::None.new
|
31
|
+
end
|
43
32
|
|
44
|
-
|
33
|
+
route %r{\A/books\Z} => Search.new(books_index, :weights => { [:title, :author] => +3, [:title] => +1 })
|
45
34
|
|
46
35
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: picky-generators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 2.0.0.
|
5
|
+
version: 2.0.0.pre2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Florian Hanke
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-21 00:00:00 +01:00
|
14
14
|
default_executable: picky-generate
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 2.0.0.
|
35
|
+
version: 2.0.0.pre2
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id002
|
38
38
|
- !ruby/object:Gem::Dependency
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 2.0.0.
|
46
|
+
version: 2.0.0.pre2
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id003
|
49
49
|
description: Generators for Picky.
|