birdgrinder 0.1.0.0
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.
- data/bin/birdgrinder +34 -0
- data/examples/bird_grinder_client.rb +45 -0
- data/lib/bird_grinder/base.rb +134 -0
- data/lib/bird_grinder/cacheable.rb +66 -0
- data/lib/bird_grinder/client.rb +136 -0
- data/lib/bird_grinder/command_handler.rb +84 -0
- data/lib/bird_grinder/console.rb +42 -0
- data/lib/bird_grinder/exceptions.rb +6 -0
- data/lib/bird_grinder/loader.rb +5 -0
- data/lib/bird_grinder/queue_processor.rb +86 -0
- data/lib/bird_grinder/tweeter/search.rb +71 -0
- data/lib/bird_grinder/tweeter/stream_processor.rb +46 -0
- data/lib/bird_grinder/tweeter/streaming.rb +74 -0
- data/lib/bird_grinder/tweeter.rb +234 -0
- data/lib/bird_grinder.rb +29 -0
- data/lib/birdgrinder.rb +1 -0
- data/lib/moneta/basic_file.rb +113 -0
- data/lib/moneta/redis.rb +49 -0
- data/templates/boot.erb +3 -0
- data/templates/debug_handler.erb +13 -0
- data/templates/hello_world_handler.erb +10 -0
- data/templates/rakefile.erb +15 -0
- data/templates/settings.yml.erb +4 -0
- data/templates/setup.erb +40 -0
- data/templates/test_helper.erb +17 -0
- data/test/bird_grinder_test.rb +9 -0
- data/test/test_helper.rb +35 -0
- metadata +140 -0
data/lib/bird_grinder.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib_path = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
3
|
+
require 'perennial'
|
4
|
+
require 'yajl'
|
5
|
+
require 'eventmachine'
|
6
|
+
require 'em-http'
|
7
|
+
|
8
|
+
module BirdGrinder
|
9
|
+
include Perennial
|
10
|
+
|
11
|
+
VERSION = [0, 1, 0, 0]
|
12
|
+
|
13
|
+
def self.version(include_minor = false)
|
14
|
+
VERSION[0, (include_minor ? 4 : 3)].join(".")
|
15
|
+
end
|
16
|
+
|
17
|
+
manifest do |m, l|
|
18
|
+
Settings.lookup_key_path = []
|
19
|
+
Settings.root = __FILE__.to_pathname.dirname.dirname
|
20
|
+
l.register_controller :client, 'BirdGrinder::Client'
|
21
|
+
l.register_controller :console, 'BirdGrinder::Console'
|
22
|
+
end
|
23
|
+
|
24
|
+
has_library :cacheable, :tweeter, :client, :base, :command_handler,
|
25
|
+
:console, :queue_processor
|
26
|
+
|
27
|
+
extends_library :loader
|
28
|
+
|
29
|
+
end
|
data/lib/birdgrinder.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "bird_grinder")
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#
|
2
|
+
# Basic File Store
|
3
|
+
# by Hampton Catlin
|
4
|
+
#
|
5
|
+
# This cache simply uses a directory that it creates
|
6
|
+
# and manages to keep your file stores.
|
7
|
+
#
|
8
|
+
# Specify :skip_expires => true if you aren't using
|
9
|
+
# expiration as this will slightly decrease your file size
|
10
|
+
# and memory footprint of the library
|
11
|
+
#
|
12
|
+
# You can optionally also specify a :namespace
|
13
|
+
# option that will create a subfolder.
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
require 'fileutils'
|
18
|
+
require 'moneta'
|
19
|
+
|
20
|
+
module Moneta
|
21
|
+
class BasicFile
|
22
|
+
include Defaults
|
23
|
+
|
24
|
+
def initialize(options = {})
|
25
|
+
@namespace = options[:namespace]
|
26
|
+
@directory = ::File.join(options[:path], @namespace.to_s)
|
27
|
+
|
28
|
+
@expires = !options[:skip_expires]
|
29
|
+
|
30
|
+
ensure_directory_created(@directory)
|
31
|
+
end
|
32
|
+
|
33
|
+
def key?(key)
|
34
|
+
!self[key].nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
alias has_key? key?
|
38
|
+
|
39
|
+
def [](key)
|
40
|
+
if ::File.exist?(path(key))
|
41
|
+
data = raw_get(key)
|
42
|
+
if @expires
|
43
|
+
if data[:expires_at].nil? || data[:expires_at] > Time.now
|
44
|
+
data[:value]
|
45
|
+
else
|
46
|
+
delete!(key)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def raw_get(key)
|
55
|
+
Marshal.load(::File.read(path(key)))
|
56
|
+
end
|
57
|
+
|
58
|
+
def []=(key, value)
|
59
|
+
store(key, value)
|
60
|
+
end
|
61
|
+
|
62
|
+
def store(key, value, options = {})
|
63
|
+
ensure_directory_created(::File.dirname(path(key)))
|
64
|
+
::File.open(path(key), "w") do |file|
|
65
|
+
if @expires
|
66
|
+
data = {:value => value}
|
67
|
+
if options[:expires_in]
|
68
|
+
data[:expires_at] = Time.now + options[:expires_in]
|
69
|
+
end
|
70
|
+
contents = Marshal.dump(data)
|
71
|
+
else
|
72
|
+
contents = Marshal.dump(value)
|
73
|
+
end
|
74
|
+
file.puts(contents)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_key(key, options)
|
79
|
+
store(key, self[key], options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete!(key)
|
83
|
+
FileUtils.rm(path(key))
|
84
|
+
nil
|
85
|
+
rescue Errno::ENOENT
|
86
|
+
end
|
87
|
+
|
88
|
+
def delete(key)
|
89
|
+
value = self[key]
|
90
|
+
delete!(key)
|
91
|
+
value
|
92
|
+
end
|
93
|
+
|
94
|
+
def clear
|
95
|
+
FileUtils.rm_rf(@directory)
|
96
|
+
FileUtils.mkdir(@directory)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
def path(key)
|
101
|
+
::File.join(@directory, key.to_s)
|
102
|
+
end
|
103
|
+
|
104
|
+
def ensure_directory_created(directory_path)
|
105
|
+
if ::File.file?(directory_path)
|
106
|
+
raise StandardError, "The path you supplied #{directory_path} is a file"
|
107
|
+
elsif !::File.exists?(directory_path)
|
108
|
+
FileUtils.mkdir_p(directory_path)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
data/lib/moneta/redis.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
begin
|
2
|
+
require "redis"
|
3
|
+
rescue LoadError
|
4
|
+
puts "You need the redis gem to use the Redis store"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
module Moneta
|
9
|
+
class Redis
|
10
|
+
include Defaults
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@cache = ::Redis.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def key?(key)
|
17
|
+
!@cache[key].nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
alias has_key? key?
|
21
|
+
|
22
|
+
def [](key)
|
23
|
+
@cache.get(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def []=(key, value)
|
27
|
+
store(key, value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(key)
|
31
|
+
value = @cache[key]
|
32
|
+
@cache.delete(key) if value
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
def store(key, value, options = {})
|
37
|
+
@cache.set(key, value, options[:expires_in])
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_key(key, options = {})
|
41
|
+
val = @cache[key]
|
42
|
+
self.store(key, val, options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear
|
46
|
+
@cache.flush_db
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/templates/boot.erb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Use this class to debug stuff as you
|
2
|
+
# go along - e.g. dump events etc.
|
3
|
+
class DebugHandler < BirdGrinder::Base
|
4
|
+
|
5
|
+
on_event :incoming_mention do
|
6
|
+
logger.info ">> Mention from #{user} - #{options.inspect}"
|
7
|
+
end
|
8
|
+
|
9
|
+
on_event :incoming_direct_message do
|
10
|
+
logger.info ">> DM from #{user} - #{options.inspect}"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
task :default => "test:units"
|
5
|
+
|
6
|
+
namespace :test do
|
7
|
+
|
8
|
+
desc "Runs the unit tests for perennial"
|
9
|
+
Rake::TestTask.new("units") do |t|
|
10
|
+
t.pattern = 'test/*_test.rb'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/templates/setup.erb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Setup the env / start doing things.
|
2
|
+
|
3
|
+
BirdGrinder::Loader.before_run do
|
4
|
+
# Register your handler subclasses here.
|
5
|
+
# they will be auto loaded so it should
|
6
|
+
# be a matter of doing:
|
7
|
+
|
8
|
+
DebugHandler.register!
|
9
|
+
|
10
|
+
# HelloWorldHandler.register!
|
11
|
+
|
12
|
+
# ... if they're a subclass of BirdGrinder::Base / BirdGrinder::CommandHandler
|
13
|
+
# or, for any other handler,
|
14
|
+
|
15
|
+
# BirdGrinder::Client.register_handler MyHandlerClass.new
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
BirdGrinder::Loader.once_running do
|
20
|
+
# Your code goes here...
|
21
|
+
# BirdGrinder::Client.current references the current client
|
22
|
+
|
23
|
+
# Examples:
|
24
|
+
|
25
|
+
# Start up the queue processor:
|
26
|
+
# BirdGrinder::QueueProcessor.start
|
27
|
+
|
28
|
+
# Search once for "jebus"
|
29
|
+
# BirdGrinder::Client.current.search "jebus"
|
30
|
+
|
31
|
+
# Repeatedly search for "BirdGrinder"
|
32
|
+
# BirdGrinder::Client.current.search "BirdGrinder", :repeat => true
|
33
|
+
|
34
|
+
# Start streaming from the sample feed:
|
35
|
+
# BirdGrinder::Client.current.streaming.sample
|
36
|
+
|
37
|
+
# Start streaming from a keyword:
|
38
|
+
# BirdGrinder::Client.current.streaming.track 'birdgrinder'
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Testing dependencies
|
4
|
+
require 'test/unit'
|
5
|
+
require 'shoulda'
|
6
|
+
# RedGreen doesn't seem to be needed under 1.9
|
7
|
+
require 'redgreen' if RUBY_VERSION < "1.9"
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
root_directory = Pathname.new(__FILE__).dirname.join("..").expand_path
|
11
|
+
require root_directory.join("config", "boot")
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
|
15
|
+
# Add your extensions here
|
16
|
+
|
17
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Testing dependencies
|
4
|
+
require 'test/unit'
|
5
|
+
require 'shoulda'
|
6
|
+
# RedGreen doesn't seem to be needed under 1.9
|
7
|
+
require 'redgreen' if RUBY_VERSION < "1.9"
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
root_directory = Pathname.new(__FILE__).dirname.join("..").expand_path
|
11
|
+
require root_directory.join("lib", "bird_grinder")
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
# Short hand for creating a class with
|
18
|
+
# a given class_eval block.
|
19
|
+
def class_via(*args, &blk)
|
20
|
+
klass = Class.new(*args)
|
21
|
+
klass.class_eval(&blk) unless blk.blank?
|
22
|
+
return klass
|
23
|
+
end
|
24
|
+
|
25
|
+
# Short hand for creating a test class
|
26
|
+
# for a set of mixins - give it the modules
|
27
|
+
# and it will include them all.
|
28
|
+
def test_class_for(*mods, &blk)
|
29
|
+
klass = Class.new
|
30
|
+
klass.class_eval { include(*mods) }
|
31
|
+
klass.class_eval(&blk) unless blk.blank?
|
32
|
+
return klass
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: birdgrinder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Darcy Laycock
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-26 00:00:00 +08:00
|
13
|
+
default_executable: birdgrinder
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: perennial
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.0.0.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: eventmachine
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.12.8
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: brianmario-yajl-ruby
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.6.3
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: igrigorik-em-http-request
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.1.8
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: Sutto-em-redis
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.1.1
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: wycats-moneta
|
67
|
+
type: :runtime
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 0.6.0
|
74
|
+
version:
|
75
|
+
description:
|
76
|
+
email: sutto@sutto.net
|
77
|
+
executables:
|
78
|
+
- birdgrinder
|
79
|
+
extensions: []
|
80
|
+
|
81
|
+
extra_rdoc_files: []
|
82
|
+
|
83
|
+
files:
|
84
|
+
- bin/birdgrinder
|
85
|
+
- lib/bird_grinder/base.rb
|
86
|
+
- lib/bird_grinder/cacheable.rb
|
87
|
+
- lib/bird_grinder/client.rb
|
88
|
+
- lib/bird_grinder/command_handler.rb
|
89
|
+
- lib/bird_grinder/console.rb
|
90
|
+
- lib/bird_grinder/exceptions.rb
|
91
|
+
- lib/bird_grinder/loader.rb
|
92
|
+
- lib/bird_grinder/queue_processor.rb
|
93
|
+
- lib/bird_grinder/tweeter/search.rb
|
94
|
+
- lib/bird_grinder/tweeter/stream_processor.rb
|
95
|
+
- lib/bird_grinder/tweeter/streaming.rb
|
96
|
+
- lib/bird_grinder/tweeter.rb
|
97
|
+
- lib/bird_grinder.rb
|
98
|
+
- lib/birdgrinder.rb
|
99
|
+
- lib/moneta/basic_file.rb
|
100
|
+
- lib/moneta/redis.rb
|
101
|
+
- templates/boot.erb
|
102
|
+
- templates/debug_handler.erb
|
103
|
+
- templates/hello_world_handler.erb
|
104
|
+
- templates/rakefile.erb
|
105
|
+
- templates/settings.yml.erb
|
106
|
+
- templates/setup.erb
|
107
|
+
- templates/test_helper.erb
|
108
|
+
- test/bird_grinder_test.rb
|
109
|
+
- test/test_helper.rb
|
110
|
+
- examples/bird_grinder_client.rb
|
111
|
+
has_rdoc: false
|
112
|
+
homepage: http://tyrannosexaraptor.com
|
113
|
+
licenses: []
|
114
|
+
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: "0"
|
125
|
+
version:
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: "0"
|
131
|
+
version:
|
132
|
+
requirements: []
|
133
|
+
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 1.3.2
|
136
|
+
signing_key:
|
137
|
+
specification_version: 3
|
138
|
+
summary: Evented Twitter Library of Doom
|
139
|
+
test_files: []
|
140
|
+
|