Skip to content

Commit

Permalink
+ test project for statistics interface
Browse files Browse the repository at this point in the history
  • Loading branch information
floere committed Jul 2, 2012
1 parent 8cfefc2 commit e0bae77
Show file tree
Hide file tree
Showing 51 changed files with 8,061 additions and 0 deletions.
31 changes: 31 additions & 0 deletions statistics/test_project/Gemfile
@@ -0,0 +1,31 @@
source :rubygems

# Gems required by the Picky client.
#
gem 'picky-client', '~> 4.0'
gem 'i18n'
gem 'activesupport', :require => 'active_support/core_ext'
gem 'sinatra'
gem 'haml'

# Gems required by the Picky server.
#
gem 'picky', '~> 4.0'
gem 'rake'
gem 'rack'
gem 'rack_fast_escape', '2009.06.24' # Optional.
gem 'text'
gem 'multi_json'

# Optional.
#
gem 'yajl-ruby', :require => 'yajl'
gem 'activerecord', '~> 3.0', :require => 'active_record'

# Required by your project.
#
gem 'unicorn'

group :test do
gem 'rspec'
end
83 changes: 83 additions & 0 deletions statistics/test_project/Gemfile.lock
@@ -0,0 +1,83 @@
GEM
remote: http://rubygems.org/
specs:
activemodel (3.2.6)
activesupport (= 3.2.6)
builder (~> 3.0.0)
activerecord (3.2.6)
activemodel (= 3.2.6)
activesupport (= 3.2.6)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activesupport (3.2.6)
i18n (~> 0.6)
multi_json (~> 1.0)
arel (3.0.2)
builder (3.0.0)
cod (0.5.0)
diff-lcs (1.1.3)
haml (3.1.6)
i18n (0.6.0)
kgio (2.7.4)
multi_json (1.3.6)
picky (4.5.1)
activesupport (~> 3.0)
multi_json
procrastinate (~> 0.4)
rack_fast_escape
text
picky-client (4.5.1)
activesupport (>= 3.0.0)
yajl-ruby (>= 0.7.8)
procrastinate (0.4.1)
cod (~> 0.4)
state_machine (~> 0.9.4)
rack (1.4.1)
rack-protection (1.2.0)
rack
rack_fast_escape (2009.06.24)
url_escape
raindrops (0.10.0)
rake (0.9.2.2)
rspec (2.10.0)
rspec-core (~> 2.10.0)
rspec-expectations (~> 2.10.0)
rspec-mocks (~> 2.10.0)
rspec-core (2.10.1)
rspec-expectations (2.10.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.10.1)
sinatra (1.3.2)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
state_machine (0.9.4)
text (1.2.1)
tilt (1.3.3)
tzinfo (0.3.33)
unicorn (4.3.1)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
url_escape (2009.06.24)
yajl-ruby (1.1.0)

PLATFORMS
ruby

DEPENDENCIES
activerecord (~> 3.0)
activesupport
haml
i18n
multi_json
picky (~> 4.0)
picky-client (~> 4.0)
rack
rack_fast_escape (= 2009.06.24)
rake
rspec
sinatra
text
unicorn
yajl-ruby
11 changes: 11 additions & 0 deletions statistics/test_project/Rakefile
@@ -0,0 +1,11 @@
require 'picky/tasks'
require 'picky-client/tasks'

# Pass in location of your javascript files, default is "javascripts".
#
Picky::Tasks::Javascripts.new

require 'rspec'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new :spec
134 changes: 134 additions & 0 deletions statistics/test_project/app.rb
@@ -0,0 +1,134 @@
# encoding: utf-8
#
require 'sinatra/base'
require 'i18n'
require 'haml'
require 'csv'
require 'picky'
require 'picky-client'

require File.expand_path '../book', __FILE__
require File.expand_path '../logging', __FILE__

# This app shows how to integrate the Picky server directly
# inside a web app. However, if you really need performance
# and easy caching, this is not recommended.
#
class BookSearch < Sinatra::Application

# We do this so we don't have to type
# Picky:: in front of everything.
#
include Picky


# Server.
#

# Data source.
#
class Books

def initialize
@csv = CSV.new File.open(File.expand_path("../data/#{PICKY_ENVIRONMENT}/library.csv", __FILE__))
end

def each
instance = Struct.new :id, :title, :author, :year
@csv.each do |row|
yield instance.new *row[0..3]
end
end

end

# Define an index.
#
books_index = Index.new :books do
source { Books.new }
indexing removes_characters: /[^a-z0-9\s\/\-\_\:\"\&\.]/i,
stopwords: /\b(and|the|of|it|in|for)\b/i,
splits_text_on: /[\s\/\-\_\:\"\&\.]/
category :title,
similarity: Similarity::DoubleMetaphone.new(3),
partial: Partial::Substring.new(from: 1) # Default is from: -3.
category :author, partial: Partial::Substring.new(from: 1)
category :year, partial: Partial::None.new
end

# Index and load on USR1 signal.
#
Signal.trap('USR1') do
books_index.reindex # kill -USR1 <pid>
end

# Define a search over the books index.
#
books = Search.new books_index do
searching substitutes_characters_with: CharacterSubstituters::WestEuropean.new, # Normalizes special user input, Ä -> Ae, ñ -> n etc.
removes_characters: /[^\p{L}\p{N}\s\/\-\_\&\.\"\~\*\:\,]/i, # Picky needs control chars *"~:, to pass through.
stopwords: /\b(and|the|of|it|in|for)\b/i,
splits_text_on: /[\s\/\-\&]+/

boost [:title, :author] => +3,
[:title] => +1
end


# Client.
#

set :static, true
set :public, File.dirname(__FILE__)
set :views, File.expand_path('../views', __FILE__)
set :haml, :format => :html5

# Root, the search page.
#
get '/' do
@query = params[:q]

haml :'/search'
end

# Renders the results into the json.
#
# You get the results from the (local) picky server and then
# populate the result hash with rendered models.
#
get '/search/full' do
results = books.search params[:query], params[:ids] || 20, params[:offset] || 0
AppLogger.info results
results = results.to_hash
results.extend Picky::Convenience
results.populate_with Book do |book|
book.to_s
end

#
# Or, to populate with the model instances, use:
# results.populate_with Book
#
# Then to render:
# rendered_entries = results.entries.map do |book| (render each book here) end
#

Yajl::Encoder.encode results
end

# Updates the search count while the user is typing.
#
get '/search/live' do
results = books.search params[:query], params[:ids] || 20, params[:offset] || 0
results.to_json
end

helpers do

def js path
"<script src='javascripts/#{path}.js' type='text/javascript'></script>"
end

end

end
42 changes: 42 additions & 0 deletions statistics/test_project/book.rb
@@ -0,0 +1,42 @@
require 'csv'

# A book is simple, it has just:
# * a title
# * an author
# * an isbn
# * a publishing year
# * a publisher
# * a number of subjects
#
class Book

@@books_mapping = {}

# Load the books on startup.
#
file_name = File.expand_path "data/#{PICKY_ENVIRONMENT}/library.csv", File.dirname(__FILE__)
CSV.open(file_name, 'r').each do |row|
@@books_mapping[row.shift.to_i] = row
end

# Find uses a lookup table.
#
def self.find ids, _ = {}
ids.map { |id| new(id, *@@books_mapping[id]) }
end

attr_reader :id

def initialize id, title, author, year, publisher, subjects
@id, @title, @author, @year, @publisher, @subjects = id, title, author, year, publisher, subjects
end

# "Rendering" ;)
#
# Note: This is just an example. Please do not render in the model.
#
def to_s
"<li class='book'><h3><a href='http://google.com?q=#{@title}'>#{@title}</a></h3><em>#{@author}</em><p>#{@year}, #{@publisher}</p><p>#{@subjects}</p></li>"
end

end
16 changes: 16 additions & 0 deletions statistics/test_project/config.ru
@@ -0,0 +1,16 @@
# Load application.
#
require File.expand_path '../app', __FILE__

# Load all indexes.
#
Picky::Indexes.load

# Use Harakiri middleware to kill unicorn child after X requests.
#
# See http://vimeo.com/12614970 for more info.
#
# Rack::Harakiri.after = 1000
# use Rack::Harakiri

run BookSearch

0 comments on commit e0bae77

Please sign in to comment.