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.
@@ -2,7 +2,7 @@ source :gemcutter
2
2
 
3
3
  # Gems required by the Picky client.
4
4
  #
5
- gem 'picky-client', '2.0.0.pre1'
5
+ gem 'picky-client', '2.0.0.pre2'
6
6
  gem 'i18n'
7
7
  gem 'activesupport', :require => 'active_support/core_ext'
8
8
  gem 'sinatra'
@@ -2,21 +2,22 @@ require 'rubygems'
2
2
  require 'bundler'
3
3
  Bundler.require
4
4
 
5
- # Load the "model".
5
+ # Sinatra settings.
6
6
  #
7
- require File.expand_path 'book', File.dirname(__FILE__)
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
- set :haml, { :format => :html5 }
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
- set :static, true
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
- # Configure. The configuration info page.
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.to_s
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
- # Normally, you'd actually go directly to the search server without taking the detour.
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
@@ -35,7 +35,7 @@ class Book
35
35
  #
36
36
  # Note: This is just an example. Please do not render in the model.
37
37
  #
38
- def to_s
38
+ def render
39
39
  "<li class='book'><p>\"#{@title}\", by #{@author}</p><p>#{@year}, #{@publisher}</p><p>#{@subjects}</p></li>"
40
40
  end
41
41
 
@@ -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=function(a,b){if($.inArray(b.keyCode,
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);">&uarr;</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]||
@@ -7,7 +7,7 @@ body {
7
7
  text-align: left; }
8
8
 
9
9
  img {
10
- margin: -2px 0px 0px; }
10
+ margin: 0px 0px -210px; }
11
11
 
12
12
  p span.explanation {
13
13
  color: #999999; }
@@ -61,7 +61,8 @@
61
61
  //
62
62
  full: '/search/full',
63
63
 
64
- // A live query just updates the count.
64
+ // A live query just updates the count and does not need
65
+ // to render (could go straight to the search server).
65
66
  //
66
67
  live: '/search/live',
67
68
 
@@ -2,7 +2,7 @@ source :gemcutter
2
2
 
3
3
  # Gems required by Picky.
4
4
  #
5
- gem 'picky', '2.0.0.pre1'
5
+ gem 'picky', '2.0.0.pre2'
6
6
  gem 'rake'
7
7
  gem 'bundler'
8
8
  gem 'rack', '~> 1.2.2'
@@ -3,44 +3,33 @@
3
3
  # TODO Adapt the generated example
4
4
  # (a library books finder) to what you need.
5
5
  #
6
- # Check the Wiki http://github.com/floere/picky/wiki for more options.
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
- # Indexing: How text is indexed.
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
- # Querying: How query text is handled.
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
- # Define an index. Use a database etc. source? Use an in-memory index or Redis?
27
- # See http://github.com/floere/picky/wiki/Sources-Configuration#sources
28
- #
29
- books_index = Index::Memory.new :books, Sources::CSV.new(:title, :author, :year, file: 'app/library.csv')
30
- books_index.define_category :title,
31
- similarity: Similarity::Phonetic.new(3), # Up to three similar title word indexed (default: No similarity).
32
- partial: Partial::Substring.new(from: 1) # Indexes substrings upwards from character 1 (default: -3),
33
- # You'll find "picky" even when entering just a "p".
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
- # Note: You can pass a query multiple indexes and it will query in all of them.
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.pre1
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-18 00:00:00 +01:00
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.pre1
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.pre1
46
+ version: 2.0.0.pre2
47
47
  type: :runtime
48
48
  version_requirements: *id003
49
49
  description: Generators for Picky.