picky-generators 2.0.0.pre1 → 2.0.0.pre2

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.
@@ -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.