bhauman-twroute 0.1.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/.document +5 -0
- data/.gitignore +10 -0
- data/README.rdoc +13 -0
- data/Rakefile +91 -0
- data/VERSION +1 -0
- data/example_app/Rakefile +5 -0
- data/example_app/config/config.yml.sample +16 -0
- data/example_app/config/twroutes.rb +3 -0
- data/example_app/scripts/twrouter.rb +10 -0
- data/lib/twroute/application/config.rb +30 -0
- data/lib/twroute/application/twrouter.rb +27 -0
- data/lib/twroute/application.rb +22 -0
- data/lib/twroute/dispatcher.rb +48 -0
- data/lib/twroute/parser/regex.rb +42 -0
- data/lib/twroute/parser/tags.rb +26 -0
- data/lib/twroute/parser/users.rb +27 -0
- data/lib/twroute/requester/basic.rb +13 -0
- data/lib/twroute/requester/delayed/create_delayed_jobs.rb +21 -0
- data/lib/twroute/requester/delayed/db_connection.rb +8 -0
- data/lib/twroute/requester/delayed.rb +21 -0
- data/lib/twroute/routes.rb +22 -0
- data/lib/twroute/tasks.rb +60 -0
- data/lib/twroute/tweet_printer.rb +7 -0
- data/lib/twroute/tweet_route.rb +64 -0
- data/lib/twroute/tweeter.rb +35 -0
- data/lib/twroute.rb +12 -0
- data/test/config_test.rb +19 -0
- data/test/dispatcher_test.rb +62 -0
- data/test/fixtures/config.yml +16 -0
- data/test/reqex_parser_test.rb +27 -0
- data/test/routes_test.rb +25 -0
- data/test/tags_parser_test.rb +30 -0
- data/test/test_helper.rb +15 -0
- data/test/test_suite.rb +11 -0
- data/test/tweet_maker.rb +47 -0
- data/test/tweet_maker_test.rb +13 -0
- data/test/tweet_route_test.rb +30 -0
- data/test/tweeter_test.rb +33 -0
- data/test/users_parser_test.rb +30 -0
- data/twroute.gemspec +96 -0
- metadata +133 -0
data/.document
ADDED
data/.gitignore
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
= Twroute - Route Twitter status updates over http to your web app
|
2
|
+
|
3
|
+
As a Rails developer the motivation to write this gem is because
|
4
|
+
I wanted a super simple way to write a twitter app where my app
|
5
|
+
can recieve messages from twitter over http and respond to the sender
|
6
|
+
over http.
|
7
|
+
|
8
|
+
In other words a controller can recieve a tweet and then reply to the
|
9
|
+
sender by simply rendering a view.
|
10
|
+
|
11
|
+
Cool huh? Well I like it.
|
12
|
+
|
13
|
+
== more docs soon?
|
data/Rakefile
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
5
|
+
|
6
|
+
|
7
|
+
namespace :jobs do
|
8
|
+
desc "Clear the delayed_job queue."
|
9
|
+
task :clear do
|
10
|
+
|
11
|
+
Delayed::Job.delete_all
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Start a delayed_job worker."
|
15
|
+
task :work do
|
16
|
+
#require 'twroute'
|
17
|
+
#require 'twroute/requester/delayed'
|
18
|
+
#require 'twroute/requester/delayed/create_delayed_jobs'
|
19
|
+
Delayed::Worker.new(:min_priority => ENV['MIN_PRIORITY'], :max_priority => ENV['MAX_PRIORITY']).start
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'creates delayed job database: not implemented'
|
23
|
+
desc :create_database do
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Create delayed_job table"
|
28
|
+
task :create_table do
|
29
|
+
CreateDelayedJobs.migrate(:up)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Create delayed_job table"
|
33
|
+
task :drop_table do
|
34
|
+
CreateDelayedJobs.migrate(:down)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
require 'jeweler'
|
40
|
+
Jeweler::Tasks.new do |gem|
|
41
|
+
gem.name = "twroute"
|
42
|
+
gem.summary = %Q{Twroute listens for Twitter updates and redirects them to HTTP post requests}
|
43
|
+
gem.description = %Q{Twroute listens for Twitter updates and redirects them to HTTP post requests}
|
44
|
+
gem.email = "bhauman@gmail.com"
|
45
|
+
gem.homepage = "http://github.com/bhauman/twroute"
|
46
|
+
gem.authors = ["bhauman"]
|
47
|
+
gem.add_dependency('activerecord', '>= 2.1.0')
|
48
|
+
gem.add_dependency('tobi-delayed_job', '>= 1.7.0')
|
49
|
+
gem.add_dependency('brianmario-yajl-ruby', '>= 0.5.12')
|
50
|
+
gem.add_dependency('deamons', '>= 1.0.10')
|
51
|
+
end
|
52
|
+
|
53
|
+
rescue LoadError
|
54
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'rake/testtask'
|
58
|
+
Rake::TestTask.new(:test) do |test|
|
59
|
+
test.libs << 'lib' << 'test'
|
60
|
+
test.pattern = 'test/**/*_test.rb'
|
61
|
+
test.verbose = true
|
62
|
+
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
require 'rcov/rcovtask'
|
66
|
+
Rcov::RcovTask.new do |test|
|
67
|
+
test.libs << 'test'
|
68
|
+
test.pattern = 'test/**/*_test.rb'
|
69
|
+
test.verbose = true
|
70
|
+
end
|
71
|
+
rescue LoadError
|
72
|
+
task :rcov do
|
73
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
task :default => :test
|
78
|
+
|
79
|
+
require 'rake/rdoctask'
|
80
|
+
Rake::RDocTask.new do |rdoc|
|
81
|
+
if File.exist?('VERSION')
|
82
|
+
version = File.read('VERSION')
|
83
|
+
else
|
84
|
+
version = ""
|
85
|
+
end
|
86
|
+
|
87
|
+
rdoc.rdoc_dir = 'rdoc'
|
88
|
+
rdoc.title = "twroute #{version}"
|
89
|
+
rdoc.rdoc_files.include('README*')
|
90
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
91
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
submit_to:
|
2
|
+
host: localhost
|
3
|
+
port: 3000
|
4
|
+
http_auth_user: ''
|
5
|
+
http_auth_password: ''
|
6
|
+
twitter:
|
7
|
+
user: ''
|
8
|
+
password: ''
|
9
|
+
stream_api: track
|
10
|
+
stream_api_args:
|
11
|
+
track: twitter
|
12
|
+
database:
|
13
|
+
adapter: sqlite3
|
14
|
+
database: db/twroute.sqlite3
|
15
|
+
pool: 5
|
16
|
+
timeout: 5000
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'daemons'
|
4
|
+
require 'twroute'
|
5
|
+
require 'twroute/application'
|
6
|
+
|
7
|
+
Daemons.run_proc('twrout_proc.rb') do
|
8
|
+
ActiveRecord::Base.logger = Logger.new(File.open(File.join(::Twroute::Application.root_dir, 'log/database.log'), 'a'))
|
9
|
+
Twroute::Application.run
|
10
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Twroute
|
5
|
+
module Application
|
6
|
+
def self.config
|
7
|
+
@@config ||= { }
|
8
|
+
end
|
9
|
+
def self.config=(config)
|
10
|
+
@@config = config
|
11
|
+
end
|
12
|
+
def self.root_dir
|
13
|
+
@@root_dir ||= Dir.pwd
|
14
|
+
end
|
15
|
+
def self.root_dir=(root)
|
16
|
+
@@root_dir = root
|
17
|
+
end
|
18
|
+
class Config
|
19
|
+
def self.load_config(file)
|
20
|
+
Application.config = self.open_struct(YAML.load_file(file))
|
21
|
+
end
|
22
|
+
def self.open_struct(hash)
|
23
|
+
hash.inject(OpenStruct.new) do |result, (key, value)|
|
24
|
+
result.send(key + '=', value.is_a?(Hash) ? open_struct(value) : value)
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'twroute/requester/delayed'
|
2
|
+
|
3
|
+
module Twroute
|
4
|
+
module Application
|
5
|
+
class Twrouter
|
6
|
+
attr_accessor :config
|
7
|
+
def initialize
|
8
|
+
self.config = ::Twroute::Application.config
|
9
|
+
setup
|
10
|
+
end
|
11
|
+
def setup
|
12
|
+
@tweeter = ::Twroute::Tweeter.new(config.twitter.user,
|
13
|
+
config.twitter.password,
|
14
|
+
config.twitter.stream_api,
|
15
|
+
config.twitter.stream_api_args.marshal_dump)
|
16
|
+
@dispatcher = ::Twroute::Dispatcher.new( config.submit_to.marshal_dump,
|
17
|
+
*::Twroute::Routes.routes )
|
18
|
+
@requester = ::Twroute::Requester::Delayed.new
|
19
|
+
@tweeter.add_observer @dispatcher
|
20
|
+
@dispatcher.add_observer @requester
|
21
|
+
end
|
22
|
+
def start
|
23
|
+
@tweeter.start
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# load the routes
|
2
|
+
require File.join(Dir.pwd, 'config', 'twroutes.rb')
|
3
|
+
|
4
|
+
# load the config
|
5
|
+
require 'twroute/application/config'
|
6
|
+
::Twroute::Application::Config.load_config(File.join(Dir.pwd, 'config', 'config.yml'))
|
7
|
+
::Twroute::Application.root_dir = Dir.pwd
|
8
|
+
|
9
|
+
# this pulls in delayed job and is dependant on the config having been read
|
10
|
+
require 'twroute/application/twrouter'
|
11
|
+
module Twroute
|
12
|
+
module Application
|
13
|
+
def self.run
|
14
|
+
@@twrouter = ::Twroute::Application::Twrouter.new
|
15
|
+
@@twrouter.start
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Twroute
|
4
|
+
class Dispatcher
|
5
|
+
include Observable
|
6
|
+
|
7
|
+
attr_accessor :tweet_routes
|
8
|
+
|
9
|
+
def initialize(options, *args)
|
10
|
+
@options = {
|
11
|
+
:host => "",
|
12
|
+
:port => false,
|
13
|
+
:http_auth_user => false,
|
14
|
+
:http_auth_password => false
|
15
|
+
}.merge(options)
|
16
|
+
self.tweet_routes = [*args]
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(tweet_hash)
|
20
|
+
route = find_route(tweet_hash)
|
21
|
+
dispatch_route(route) if route
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_route(tweet_hash)
|
25
|
+
tweet_routes.find do |route|
|
26
|
+
route.tweet(tweet_hash)
|
27
|
+
return route if route.is_match?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def dispatch_route(route)
|
32
|
+
uri = get_uri(route)
|
33
|
+
post_args = route.get_post_args
|
34
|
+
changed
|
35
|
+
notify_observers(uri, post_args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_uri(route)
|
39
|
+
url = "http://"
|
40
|
+
url += "#{@options[:http_auth_user]}:#{@options[:http_auth_password]}@" if @options[:http_auth_user] && @options[:http_auth_password]
|
41
|
+
url += "#{@options[:host]}"
|
42
|
+
url += ":#{@options[:port]}" if @options[:port]
|
43
|
+
url += route.path
|
44
|
+
URI.parse(url)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Twroute
|
2
|
+
module Parser
|
3
|
+
class Regex
|
4
|
+
attr_accessor :regex_hash
|
5
|
+
|
6
|
+
def initialize(regex_hash)
|
7
|
+
self.regex_hash = regex_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_tweet(tweet_text)
|
11
|
+
@parsed_hash = parse_to_hash(tweet_text)
|
12
|
+
is_match? ? @parsed_hash : false
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_match?
|
16
|
+
@parsed_hash.values.inject(true) do |accum, val|
|
17
|
+
accum && !!val
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_to_hash(tweet_text)
|
22
|
+
regex_hash.inject({ }) do |accum, key_val|
|
23
|
+
match_data = tweet_text.match(key_val.last)
|
24
|
+
accum[key_val.first] = (process_data(match_data) ? match_data[0] : nil)
|
25
|
+
accum
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# delayed job can't unmarshal things that have lines that end in :
|
30
|
+
def process_data(data)
|
31
|
+
if(data && data.is_a?(String))
|
32
|
+
data.gsub(/:$/m, '')
|
33
|
+
else
|
34
|
+
data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Twroute
|
2
|
+
module Parser
|
3
|
+
class Tags
|
4
|
+
TAG_REGEX = /\#([\w\d_]+)/
|
5
|
+
|
6
|
+
def parse_tweet(tweet_text)
|
7
|
+
@parsed_hash = parse_to_hash(tweet_text)
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_match?
|
11
|
+
!@parsed_hash.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_to_hash(tweet_text)
|
15
|
+
tags = parse_tags_out(tweet_text)
|
16
|
+
return { } if tags.empty?
|
17
|
+
{ :tags => tags.join('-') }
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_tags_out(tweet_text = "")
|
21
|
+
tweet_text.scan(TAG_REGEX).to_a.flatten
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Twroute
|
2
|
+
module Parser
|
3
|
+
class Users
|
4
|
+
USERS_REGEX = /\@([\w\d_]+)/
|
5
|
+
|
6
|
+
def parse_tweet(tweet_text)
|
7
|
+
@parsed_hash = parse_to_hash(tweet_text)
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_match?
|
11
|
+
!@parsed_hash.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_to_hash(tweet_text)
|
15
|
+
users = parse_users_out(tweet_text)
|
16
|
+
return { } if users.empty?
|
17
|
+
{ :users => users.join('-') }
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_users_out(tweet_text = "")
|
21
|
+
tweet_text.scan(USERS_REGEX).to_a.flatten
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateDelayedJobs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :delayed_jobs, :force => true do |table|
|
4
|
+
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
|
5
|
+
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
|
6
|
+
table.text :handler # YAML-encoded string of the object that will do work
|
7
|
+
table.text :last_error # reason for last failure (See Note below)
|
8
|
+
table.datetime :run_at # When to run. Could be Time.now for immediately, or sometime in the future.
|
9
|
+
table.datetime :locked_at # Set when a client is working on this object
|
10
|
+
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
11
|
+
table.string :locked_by # Who is working on this object (if locked)
|
12
|
+
table.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table :delayed_jobs
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'activerecord'
|
2
|
+
|
3
|
+
::Twroute::Application.config.database.database = File.join(::Twroute::Application.root_dir,
|
4
|
+
::Twroute::Application.config.database.database).to_s
|
5
|
+
|
6
|
+
ActiveRecord::Base.establish_connection(::Twroute::Application.config.database.marshal_dump)
|
7
|
+
|
8
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'twroute/requester/delayed/db_connection'
|
2
|
+
require 'delayed_job'
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
module Twroute
|
6
|
+
module Requester
|
7
|
+
|
8
|
+
class Delayed
|
9
|
+
def update(uri, post_args)
|
10
|
+
::Delayed::Job.enqueue DelayedRequest.new(uri, post_args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class DelayedRequest < Struct.new(:uri, :post_args)
|
15
|
+
def perform
|
16
|
+
response = Net::HTTP.post_form(uri, post_args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Twroute
|
2
|
+
class Routes
|
3
|
+
def self.routes
|
4
|
+
@@routes ||= []
|
5
|
+
@@routes
|
6
|
+
end
|
7
|
+
def self.append_route(x)
|
8
|
+
@@routes ||= []
|
9
|
+
@@routes << x
|
10
|
+
end
|
11
|
+
def self.draw(&block)
|
12
|
+
yield Collector
|
13
|
+
end
|
14
|
+
class Collector
|
15
|
+
def self.regex(regex_hash, url_pattern)
|
16
|
+
Routes.append_route(
|
17
|
+
TweetRoute.new(Parser::Regex.new(regex_hash),
|
18
|
+
url_pattern))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Twroute
|
5
|
+
class Tasks < ::Rake::TaskLib
|
6
|
+
def initialize
|
7
|
+
namespace :twroute do
|
8
|
+
task :load_env do
|
9
|
+
require 'twroute'
|
10
|
+
require 'twroute/application'
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "create database"
|
14
|
+
task :create_database => :load_env do
|
15
|
+
require 'sqlite3'
|
16
|
+
db = SQLite3::Database.new(Twroute::Application.config.database.database)
|
17
|
+
db.close
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Create delayed_job table"
|
21
|
+
task :create_table => :load_env do
|
22
|
+
require 'twroute/requester/delayed/create_delayed_jobs'
|
23
|
+
CreateDelayedJobs.migrate(:up)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "create required directories"
|
27
|
+
task :create_dirs do
|
28
|
+
require 'fileutils'
|
29
|
+
['log', 'db'].each do |dir|
|
30
|
+
FileUtils.mkdir_p(dir) if !File.exists?(dir)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "initialize twroute app : creates database : creates table : creates directories"
|
35
|
+
task :init => [:create_dirs, :create_database, :create_table] do
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Delete delayed_job table"
|
40
|
+
task :drop_table => :load_env do
|
41
|
+
require 'twroute/requester/delayed/create_delayed_jobs'
|
42
|
+
CreateDelayedJobs.migrate(:down)
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Clear the delayed_job queue."
|
46
|
+
task :clear => :load_env do
|
47
|
+
ActiveRecord::Base.logger = Logger.new(File.open('log/delayed.log', 'a'))
|
48
|
+
::Delayed::Job.delete_all
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Start a delayed_job worker."
|
52
|
+
task :work => :load_env do
|
53
|
+
ActiveRecord::Base.logger = Logger.new(File.open('log/delayed.log', 'a'))
|
54
|
+
::Delayed::Worker.new(:min_priority => ENV['MIN_PRIORITY'],
|
55
|
+
:max_priority => ENV['MAX_PRIORITY']).start
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Twroute
|
2
|
+
class TweetRoute
|
3
|
+
attr_accessor :tweet_parser, :url_pattern
|
4
|
+
def initialize(tweet_parser, url_pattern)
|
5
|
+
self.tweet_parser = tweet_parser
|
6
|
+
self.url_pattern = url_pattern
|
7
|
+
end
|
8
|
+
|
9
|
+
def tweet(tweet_hash)
|
10
|
+
reset
|
11
|
+
@tweet_hash = tweet_hash
|
12
|
+
@sender_hash = tweet_hash.delete(:user)
|
13
|
+
parse_tweet(tweet_hash[:text])
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset
|
17
|
+
@tweet_hash = { }
|
18
|
+
@sender_hash = { }
|
19
|
+
@parsed_hash = { }
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_tweet(tweet_text)
|
23
|
+
@parsed_hash = tweet_parser.parse_tweet(tweet_text) || { }
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_match?
|
27
|
+
tweet_parser.is_match?
|
28
|
+
end
|
29
|
+
|
30
|
+
def path
|
31
|
+
fill_in_url_pattern
|
32
|
+
end
|
33
|
+
|
34
|
+
def fill_in_url_pattern
|
35
|
+
pattern = self.url_pattern
|
36
|
+
@parsed_hash.keys.each do |key|
|
37
|
+
pattern.gsub!(':' + key.to_s, @parsed_hash[key])
|
38
|
+
end
|
39
|
+
|
40
|
+
tweet_h = @tweet_hash.merge({ })
|
41
|
+
tweet_h.delete(:user)
|
42
|
+
tweet_h.keys.each do |key|
|
43
|
+
pattern.gsub!(':tweet[' + key.to_s + ']', @tweet_hash[key].to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
pattern
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_post_args
|
50
|
+
post_hash = { }
|
51
|
+
@parsed_hash.keys.each do |key|
|
52
|
+
post_hash[key.to_s] = @parsed_hash[key]
|
53
|
+
end
|
54
|
+
@sender_hash.keys.each do |key|
|
55
|
+
post_hash["sender[#{key.to_s}]"] = @sender_hash[key]
|
56
|
+
end
|
57
|
+
@tweet_hash.keys.each do |key|
|
58
|
+
post_hash["tweet[#{key.to_s}]"] = @tweet_hash[key]
|
59
|
+
end
|
60
|
+
post_hash
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yajl'
|
2
|
+
require 'yajl/http_stream'
|
3
|
+
require 'observer'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Twroute
|
7
|
+
class Tweeter
|
8
|
+
include Observable
|
9
|
+
|
10
|
+
def initialize(user, password, twitter_stream, post_arg_hash = {})
|
11
|
+
@user = user
|
12
|
+
@password = password
|
13
|
+
@twitter_stream = twitter_stream
|
14
|
+
@post_arg_hash = post_arg_hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def twitter_stream_uri
|
18
|
+
URI.parse("http://#{@user}:#{@password}@stream.twitter.com/#{@twitter_stream}.json?#{self.query_string}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def query_string
|
22
|
+
@post_arg_hash.keys.collect do |key|
|
23
|
+
"#{key}=#{URI.escape(@post_arg_hash[key])}"
|
24
|
+
end.sort_by { |x| x }.join('&')
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
puts twitter_stream_uri.to_s
|
29
|
+
Yajl::HttpStream.get(twitter_stream_uri, :symbolize_keys => true) do |hash|
|
30
|
+
changed
|
31
|
+
notify_observers( hash )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/twroute.rb
ADDED
data/test/config_test.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'twroute/application/config'
|
3
|
+
|
4
|
+
class ConfigTest < Test::Unit::TestCase
|
5
|
+
include Twroute
|
6
|
+
|
7
|
+
context "with loaded config" do
|
8
|
+
setup do
|
9
|
+
file = File.join(File.dirname(__FILE__), 'fixtures', 'config.yml')
|
10
|
+
Application::Config.load_config(file)
|
11
|
+
end
|
12
|
+
should "have config loaded" do
|
13
|
+
Application.config.database.nil?.should == false
|
14
|
+
Application.config.database.adapter.should == 'sqlite3'
|
15
|
+
Application.config.twitter.stream_api_args.track.should == 'twitter'
|
16
|
+
Application.config.submit_to.host.should == 'localhost'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'twroute/dispatcher'
|
3
|
+
|
4
|
+
class DispatcherTest < Test::Unit::TestCase
|
5
|
+
include Twroute
|
6
|
+
|
7
|
+
context "with dispatcher" do
|
8
|
+
setup do
|
9
|
+
@tweet_route_user = TweetRoute.new(Parser::Regex.new({:user => /\@\w+/}), '/my_test_path/:user')
|
10
|
+
@tweet_route_tag = TweetRoute.new(Parser::Regex.new({:tag => /\#\w+/}), '/my_test_path/:tag')
|
11
|
+
@tweet_route_user_and_tag = TweetRoute.new(Parser::Regex.new({:tag => /\#\w+/,
|
12
|
+
:user => /\@\w+/ }),
|
13
|
+
'/my_test_path/:tag/:user')
|
14
|
+
@dispatcher = Dispatcher.new( {:host => 'test-host.com'},
|
15
|
+
@tweet_route_user_and_tag,
|
16
|
+
@tweet_route_user,
|
17
|
+
@tweet_route_tag )
|
18
|
+
|
19
|
+
@match_user_tweet = TweetMaker.make_tweet :text => "@this is cool too here 3about_it"
|
20
|
+
@match_tag_tweet = TweetMaker.make_tweet :text => "#this is cool too here 3about_it"
|
21
|
+
@match_user_and_tag_tweet = TweetMaker.make_tweet :text => "@random #this is cool too here 3about_it"
|
22
|
+
end
|
23
|
+
|
24
|
+
should "match be able to get the first matched route" do
|
25
|
+
@dispatcher.tweet_routes.length.should == 3
|
26
|
+
|
27
|
+
@dispatcher.find_route(@match_user_and_tag_tweet).should == @tweet_route_user_and_tag
|
28
|
+
@dispatcher.find_route(@match_user_tweet).should == @tweet_route_user
|
29
|
+
@dispatcher.find_route(@match_tag_tweet).should == @tweet_route_tag
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
should "be able to handle one route" do
|
34
|
+
disp = Dispatcher.new( {:host => 'test-host.com'},
|
35
|
+
@tweet_route_user
|
36
|
+
)
|
37
|
+
disp.find_route(@match_user_tweet).should == @tweet_route_user
|
38
|
+
end
|
39
|
+
|
40
|
+
should "to create a uri" do
|
41
|
+
disp = Dispatcher.new({:host => 'test-host.com'},
|
42
|
+
@tweet_route_user)
|
43
|
+
route = stub(:path, :return => '/path')
|
44
|
+
disp.get_uri(route).to_s.should == 'http://test-host.com/path'
|
45
|
+
disp = Dispatcher.new({:host => 'test-host.com',
|
46
|
+
:http_auth_user => 'jay'},
|
47
|
+
@tweet_route_user)
|
48
|
+
disp.get_uri(route).to_s.should == 'http://test-host.com/path'
|
49
|
+
disp = Dispatcher.new({:host => 'test-host.com',
|
50
|
+
:http_auth_user => 'jay',
|
51
|
+
:http_auth_password => 'man'},
|
52
|
+
@tweet_route_user)
|
53
|
+
disp.get_uri(route).to_s.should == 'http://jay:man@test-host.com/path'
|
54
|
+
disp = Dispatcher.new({:host => 'test-host.com',
|
55
|
+
:port => '3000'},
|
56
|
+
@tweet_route_user)
|
57
|
+
disp.get_uri(route).to_s.should == 'http://test-host.com:3000/path'
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
submit_to:
|
2
|
+
host: localhost
|
3
|
+
port: 3000
|
4
|
+
http_auth_user: auth_user
|
5
|
+
http_auth_password: auth_pass
|
6
|
+
twitter:
|
7
|
+
user: twitter_user
|
8
|
+
password: twitter_pass
|
9
|
+
stream_api: track
|
10
|
+
stream_api_args:
|
11
|
+
track: twitter
|
12
|
+
database:
|
13
|
+
adapter: sqlite3
|
14
|
+
database: db/twroute.sqlite3
|
15
|
+
pool: 5
|
16
|
+
timeout: 5000
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
|
3
|
+
class RegexParserTest < Test::Unit::TestCase
|
4
|
+
context "with regex parser" do
|
5
|
+
setup do
|
6
|
+
@regex_parser = Twroute::Parser::Regex.new(:whole => /\@\w+\s+(\#\w+\s)+for\s+(\d+)\s+(day|week|month|year)s{0,1}\s+.*/,
|
7
|
+
:user => /\@\w+/,
|
8
|
+
:tags => /(\#\w+\s)+/,
|
9
|
+
:time => /for\s+(\d+)\s+(day|week|month|year)s{0,1}/)
|
10
|
+
@tweet_str = "@johnny #this #is #cool for 17 days yeah buddy"
|
11
|
+
end
|
12
|
+
|
13
|
+
should "parse hash" do
|
14
|
+
hash = @regex_parser.parse_to_hash(@tweet_str)
|
15
|
+
assert hash
|
16
|
+
hash[:whole].should == "@johnny #this #is #cool for 17 days yeah buddy"
|
17
|
+
hash[:user].should == '@johnny'
|
18
|
+
hash[:tags].should == '#this #is #cool '
|
19
|
+
hash[:time].should == 'for 17 days'
|
20
|
+
end
|
21
|
+
|
22
|
+
should "return false if all regexes don't match" do
|
23
|
+
@regex_parser.parse_tweet("@johnny #this #is #cool 17 days yeah buddy").should == false
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/test/routes_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RoutesTest < Test::Unit::TestCase
|
4
|
+
include Twroute
|
5
|
+
context "with routes" do
|
6
|
+
setup do
|
7
|
+
Routes.draw do |map|
|
8
|
+
map.regex({ :tweet_text => /.*/ },
|
9
|
+
'/tweet/create')
|
10
|
+
map.regex({ :tweet_text => /happy/ },
|
11
|
+
'/happy/create')
|
12
|
+
map.regex({ :tweet_text => /happy2/ },
|
13
|
+
'/happy2/create')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
should "have created the tweet routes and agregated them" do
|
18
|
+
Routes.routes.length.should == 3
|
19
|
+
Routes.routes[0].is_a?(TweetRoute).should == true
|
20
|
+
Routes.routes[0].tweet_parser.is_a?(Parser::Regex).should == true
|
21
|
+
Routes.routes[0].url_pattern.should == '/tweet/create'
|
22
|
+
Routes.routes[2].url_pattern.should == '/happy2/create'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class TagsParserTest < Test::Unit::TestCase
|
3
|
+
context "with tags parser" do
|
4
|
+
setup do
|
5
|
+
@tags_parser = Twroute::Parser::Tags.new
|
6
|
+
@tags_str = "#this #is cool #too here #3about_it"
|
7
|
+
end
|
8
|
+
|
9
|
+
should "be able to determine a match" do
|
10
|
+
@tags_parser.parse_tweet(@tags_str)
|
11
|
+
@tags_parser.is_match?.should == true
|
12
|
+
@tags_parser.parse_tweet("hello there")
|
13
|
+
@tags_parser.is_match?.should == false
|
14
|
+
end
|
15
|
+
|
16
|
+
should "parse twitter tags from a string" do
|
17
|
+
@tags_parser.parse_tags_out(@tags_str).should == ['this', 'is', 'too', '3about_it']
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be able to parse nil string" do
|
21
|
+
@tags_parser.parse_tags_out().should == []
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return hash of tags" do
|
25
|
+
@tags_parser.parse_to_hash(@tags_str).should == {:tags => 'this-is-too-3about_it'}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'matchy'
|
5
|
+
require 'stump'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
+
|
10
|
+
require 'twroute'
|
11
|
+
|
12
|
+
class Test::Unit::TestCase
|
13
|
+
end
|
14
|
+
|
15
|
+
|
data/test/test_suite.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
require 'users_parser_test'
|
6
|
+
require 'tags_parser_test'
|
7
|
+
require 'reqex_parser_test'
|
8
|
+
require 'tweet_route_test'
|
9
|
+
require 'tweeter_test'
|
10
|
+
require 'tweet_maker_test'
|
11
|
+
require 'dispatcher_test'
|
data/test/tweet_maker.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class TweetMaker
|
2
|
+
|
3
|
+
def self.make_tweet(tweet_hash = { })
|
4
|
+
tweet = { }.merge(BASE_TWEET)
|
5
|
+
user = tweet_hash.delete(:user)
|
6
|
+
tweet[:user].merge!(user || { })
|
7
|
+
tweet.merge!(tweet_hash)
|
8
|
+
tweet
|
9
|
+
end
|
10
|
+
|
11
|
+
BASE_TWEET = {
|
12
|
+
:source=>"web",
|
13
|
+
:user=>{:url=>"http://test_host.com/",
|
14
|
+
:friends_count=>275,
|
15
|
+
:time_zone=>"Central Time (US & Canada)",
|
16
|
+
:screen_name=>"test_screen_name",
|
17
|
+
:notifications=>nil,
|
18
|
+
:utc_offset=>-21600,
|
19
|
+
:profile_image_url=>"http://s3.amazonaws.com/twitter_production/profile_images/352932267/twitterProfilePhoto_normal.jpg",
|
20
|
+
:protected=>false,
|
21
|
+
:verified=>false,
|
22
|
+
:profile_text_color=>"000000",
|
23
|
+
:name=>"test_name",
|
24
|
+
:profile_sidebar_border_color=>"D5D39E",
|
25
|
+
:statuses_count=>625,
|
26
|
+
:profile_link_color=>"B4C67C",
|
27
|
+
:location=>"Asheville NC",
|
28
|
+
:following=>nil,
|
29
|
+
:profile_background_image_url=>"http://s3.amazonaws.com/twitter_production/profile_background_images/2475770/background.png",
|
30
|
+
:description=>"I beleive that life is pretty darn cool",
|
31
|
+
:followers_count=>211,
|
32
|
+
:created_at=>"Thu May 01 02:11:28 +0000 2008",
|
33
|
+
:profile_background_tile=>true,
|
34
|
+
:id=>14609143,
|
35
|
+
:profile_background_color=>"9ae4e8",
|
36
|
+
:profile_sidebar_fill_color=>"778F5F",
|
37
|
+
:favourites_count=>19},
|
38
|
+
:text=>"this is a #test #tweet",
|
39
|
+
:favorited=>false,
|
40
|
+
:in_reply_to_screen_name=>nil,
|
41
|
+
:in_reply_to_status_id=>nil,
|
42
|
+
:created_at=>"Sun Aug 09 00:25:46 +0000 2009",
|
43
|
+
:id=>3199928174,
|
44
|
+
:in_reply_to_user_id=>nil,
|
45
|
+
:truncated=>false}
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'tweet_maker'
|
3
|
+
class TweetMakerTest < Test::Unit::TestCase
|
4
|
+
context "tweet maker" do
|
5
|
+
should "be able to make a tweet hash" do
|
6
|
+
tweet = TweetMaker.make_tweet({ :text => 'test test test', :user => { :name => 'testy_name'}})
|
7
|
+
tweet[:source].should == 'web'
|
8
|
+
tweet[:text].should == 'test test test'
|
9
|
+
tweet[:user][:url].should == 'http://test_host.com/'
|
10
|
+
tweet[:user][:name].should == 'testy_name'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
class TweetRouteTest < Test::Unit::TestCase
|
3
|
+
context "with users parser" do
|
4
|
+
setup do
|
5
|
+
@tweet_route = Twroute::TweetRoute.new(Twroute::Parser::Tags.new, '/user/:tweet[sender]/tags/:tags')
|
6
|
+
@tweet_str = "#this #is cool #too"
|
7
|
+
@tweet = {:source=>"<a href=\"http://twitterfox.net/\">TwitterFox</a>", :user=>{:url=>"http://rosed1st.multiply.com/", :friends_count=>275, :time_zone=>"Central Time (US & Canada)", :screen_name=>"RoseD1st", :notifications=>nil, :utc_offset=>-21600, :profile_image_url=>"http://s3.amazonaws.com/twitter_production/profile_images/352932267/twitterProfilePhoto_normal.jpg", :protected=>false, :verified=>false, :profile_text_color=>"000000", :name=>"RoseD1st", :profile_sidebar_border_color=>"D5D39E", :statuses_count=>625, :profile_link_color=>"B4C67C", :location=>"Mad as Hell!", :following=>nil, :profile_background_image_url=>"http://s3.amazonaws.com/twitter_production/profile_background_images/2475770/background.png", :description=>"A conservatve whos had it with Obamas lies!I'm a proud \342\200\234Birther\342\200\235 and only those who haven't looked at the facts think there's no problem", :followers_count=>211, :created_at=>"Thu May 01 02:11:28 +0000 2008", :profile_background_tile=>true, :id=>14609143, :profile_background_color=>"9ae4e8", :profile_sidebar_fill_color=>"778F5F", :favourites_count=>19}, :text=>"this is a #test #tweet", :favorited=>false, :in_reply_to_screen_name=>nil, :in_reply_to_status_id=>nil, :created_at=>"Sun Aug 09 00:25:46 +0000 2009", :id=>3199928174, :in_reply_to_user_id=>nil, :truncated=>false}
|
8
|
+
end
|
9
|
+
|
10
|
+
should "be able to determine if the required hash keys have been met" do
|
11
|
+
@tweet_route.parse_tweet(@tweet_str)
|
12
|
+
@tweet_route.is_match?.should == true
|
13
|
+
end
|
14
|
+
|
15
|
+
should "be able to fill in a url_pattern" do
|
16
|
+
@tweet_route.tweet({ :text => @tweet_str, :sender => 'charlie' })
|
17
|
+
@tweet_route.fill_in_url_pattern.should == '/user/charlie/tags/this-is-too'
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be able to generate post args" do
|
21
|
+
@tweet_route.tweet(@tweet)
|
22
|
+
post_args = @tweet_route.get_post_args
|
23
|
+
post_args['sender[screen_name]'].should == 'RoseD1st'
|
24
|
+
post_args['tweet[text]'].should == 'this is a #test #tweet'
|
25
|
+
post_args['tags'].should == 'test-tweet'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
require 'tweeter'
|
3
|
+
|
4
|
+
class TweeterTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with tweeter" do
|
12
|
+
setup do
|
13
|
+
@tweeter = Twroute::Tweeter.new('bhauman',
|
14
|
+
'watertank',
|
15
|
+
'track',
|
16
|
+
:track => 'twitter' )
|
17
|
+
end
|
18
|
+
|
19
|
+
should "be able to create query string" do
|
20
|
+
@tweeter = Twroute::Tweeter.new('bhauman',
|
21
|
+
'watertank',
|
22
|
+
'track',
|
23
|
+
:track => 'twitter', :twank => 'twonkle' )
|
24
|
+
@tweeter.query_string.should == 'track=twitter&twank=twonkle'
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to create a twitter search url" do
|
28
|
+
@tweeter.twitter_stream_uri.to_s.should == 'http://bhauman:watertank@stream.twitter.com/track.json?track=twitter'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class UsersParserTest < Test::Unit::TestCase
|
3
|
+
context "with users parser" do
|
4
|
+
setup do
|
5
|
+
@users_parser = Twroute::Parser::Users.new
|
6
|
+
@users_str = "@this @is cool @too here @3about_it"
|
7
|
+
end
|
8
|
+
|
9
|
+
should "be able to determine a match" do
|
10
|
+
@users_parser.parse_tweet(@users_str)
|
11
|
+
@users_parser.is_match?.should == true
|
12
|
+
@users_parser.parse_tweet("hello there")
|
13
|
+
@users_parser.is_match?.should == false
|
14
|
+
end
|
15
|
+
|
16
|
+
should "parse twitter users from a string" do
|
17
|
+
@users_parser.parse_users_out(@users_str).should == ['this', 'is', 'too', '3about_it']
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be able to parse nil string" do
|
21
|
+
@users_parser.parse_users_out().should == []
|
22
|
+
end
|
23
|
+
|
24
|
+
should "return hash of users" do
|
25
|
+
@users_parser.parse_to_hash(@users_str).should == {:users => 'this-is-too-3about_it'}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/twroute.gemspec
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{twroute}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["bhauman"]
|
9
|
+
s.date = %q{2009-08-12}
|
10
|
+
s.description = %q{Twroute listens for Twitter updates and redirects them to HTTP post requests}
|
11
|
+
s.email = %q{bhauman@gmail.com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"README.rdoc",
|
19
|
+
"Rakefile",
|
20
|
+
"VERSION",
|
21
|
+
"example_app/Rakefile",
|
22
|
+
"example_app/config/config.yml.sample",
|
23
|
+
"example_app/config/twroutes.rb",
|
24
|
+
"example_app/scripts/twrouter.rb",
|
25
|
+
"lib/twroute.rb",
|
26
|
+
"lib/twroute/application.rb",
|
27
|
+
"lib/twroute/application/config.rb",
|
28
|
+
"lib/twroute/application/twrouter.rb",
|
29
|
+
"lib/twroute/dispatcher.rb",
|
30
|
+
"lib/twroute/parser/regex.rb",
|
31
|
+
"lib/twroute/parser/tags.rb",
|
32
|
+
"lib/twroute/parser/users.rb",
|
33
|
+
"lib/twroute/requester/basic.rb",
|
34
|
+
"lib/twroute/requester/delayed.rb",
|
35
|
+
"lib/twroute/requester/delayed/create_delayed_jobs.rb",
|
36
|
+
"lib/twroute/requester/delayed/db_connection.rb",
|
37
|
+
"lib/twroute/routes.rb",
|
38
|
+
"lib/twroute/tasks.rb",
|
39
|
+
"lib/twroute/tweet_printer.rb",
|
40
|
+
"lib/twroute/tweet_route.rb",
|
41
|
+
"lib/twroute/tweeter.rb",
|
42
|
+
"test/config_test.rb",
|
43
|
+
"test/dispatcher_test.rb",
|
44
|
+
"test/fixtures/config.yml",
|
45
|
+
"test/reqex_parser_test.rb",
|
46
|
+
"test/routes_test.rb",
|
47
|
+
"test/tags_parser_test.rb",
|
48
|
+
"test/test_helper.rb",
|
49
|
+
"test/test_suite.rb",
|
50
|
+
"test/tweet_maker.rb",
|
51
|
+
"test/tweet_maker_test.rb",
|
52
|
+
"test/tweet_route_test.rb",
|
53
|
+
"test/tweeter_test.rb",
|
54
|
+
"test/users_parser_test.rb",
|
55
|
+
"twroute.gemspec"
|
56
|
+
]
|
57
|
+
s.has_rdoc = true
|
58
|
+
s.homepage = %q{http://github.com/bhauman/twroute}
|
59
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
60
|
+
s.require_paths = ["lib"]
|
61
|
+
s.rubygems_version = %q{1.3.1}
|
62
|
+
s.summary = %q{Twroute listens for Twitter updates and redirects them to HTTP post requests}
|
63
|
+
s.test_files = [
|
64
|
+
"test/config_test.rb",
|
65
|
+
"test/dispatcher_test.rb",
|
66
|
+
"test/reqex_parser_test.rb",
|
67
|
+
"test/routes_test.rb",
|
68
|
+
"test/tags_parser_test.rb",
|
69
|
+
"test/test_helper.rb",
|
70
|
+
"test/test_suite.rb",
|
71
|
+
"test/tweet_maker.rb",
|
72
|
+
"test/tweet_maker_test.rb",
|
73
|
+
"test/tweet_route_test.rb",
|
74
|
+
"test/tweeter_test.rb",
|
75
|
+
"test/users_parser_test.rb"
|
76
|
+
]
|
77
|
+
|
78
|
+
if s.respond_to? :specification_version then
|
79
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
80
|
+
s.specification_version = 2
|
81
|
+
|
82
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
83
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 2.1.0"])
|
84
|
+
s.add_runtime_dependency(%q<tobi-delayed_job>, [">= 1.7.0"])
|
85
|
+
s.add_runtime_dependency(%q<brianmario-yajl-ruby>, [">= 0.5.12"])
|
86
|
+
else
|
87
|
+
s.add_dependency(%q<activerecord>, [">= 2.1.0"])
|
88
|
+
s.add_dependency(%q<tobi-delayed_job>, [">= 1.7.0"])
|
89
|
+
s.add_dependency(%q<brianmario-yajl-ruby>, [">= 0.5.12"])
|
90
|
+
end
|
91
|
+
else
|
92
|
+
s.add_dependency(%q<activerecord>, [">= 2.1.0"])
|
93
|
+
s.add_dependency(%q<tobi-delayed_job>, [">= 1.7.0"])
|
94
|
+
s.add_dependency(%q<brianmario-yajl-ruby>, [">= 0.5.12"])
|
95
|
+
end
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bhauman-twroute
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- bhauman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-12 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.1.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: tobi-delayed_job
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.7.0
|
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.5.12
|
44
|
+
version:
|
45
|
+
description: Twroute listens for Twitter updates and redirects them to HTTP post requests
|
46
|
+
email: bhauman@gmail.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- README.rdoc
|
53
|
+
files:
|
54
|
+
- .document
|
55
|
+
- .gitignore
|
56
|
+
- README.rdoc
|
57
|
+
- Rakefile
|
58
|
+
- VERSION
|
59
|
+
- example_app/Rakefile
|
60
|
+
- example_app/config/config.yml.sample
|
61
|
+
- example_app/config/twroutes.rb
|
62
|
+
- example_app/scripts/twrouter.rb
|
63
|
+
- lib/twroute.rb
|
64
|
+
- lib/twroute/application.rb
|
65
|
+
- lib/twroute/application/config.rb
|
66
|
+
- lib/twroute/application/twrouter.rb
|
67
|
+
- lib/twroute/dispatcher.rb
|
68
|
+
- lib/twroute/parser/regex.rb
|
69
|
+
- lib/twroute/parser/tags.rb
|
70
|
+
- lib/twroute/parser/users.rb
|
71
|
+
- lib/twroute/requester/basic.rb
|
72
|
+
- lib/twroute/requester/delayed.rb
|
73
|
+
- lib/twroute/requester/delayed/create_delayed_jobs.rb
|
74
|
+
- lib/twroute/requester/delayed/db_connection.rb
|
75
|
+
- lib/twroute/routes.rb
|
76
|
+
- lib/twroute/tasks.rb
|
77
|
+
- lib/twroute/tweet_printer.rb
|
78
|
+
- lib/twroute/tweet_route.rb
|
79
|
+
- lib/twroute/tweeter.rb
|
80
|
+
- test/config_test.rb
|
81
|
+
- test/dispatcher_test.rb
|
82
|
+
- test/fixtures/config.yml
|
83
|
+
- test/reqex_parser_test.rb
|
84
|
+
- test/routes_test.rb
|
85
|
+
- test/tags_parser_test.rb
|
86
|
+
- test/test_helper.rb
|
87
|
+
- test/test_suite.rb
|
88
|
+
- test/tweet_maker.rb
|
89
|
+
- test/tweet_maker_test.rb
|
90
|
+
- test/tweet_route_test.rb
|
91
|
+
- test/tweeter_test.rb
|
92
|
+
- test/users_parser_test.rb
|
93
|
+
- twroute.gemspec
|
94
|
+
has_rdoc: true
|
95
|
+
homepage: http://github.com/bhauman/twroute
|
96
|
+
licenses:
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options:
|
99
|
+
- --charset=UTF-8
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "0"
|
107
|
+
version:
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0"
|
113
|
+
version:
|
114
|
+
requirements: []
|
115
|
+
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 1.3.5
|
118
|
+
signing_key:
|
119
|
+
specification_version: 2
|
120
|
+
summary: Twroute listens for Twitter updates and redirects them to HTTP post requests
|
121
|
+
test_files:
|
122
|
+
- test/config_test.rb
|
123
|
+
- test/dispatcher_test.rb
|
124
|
+
- test/reqex_parser_test.rb
|
125
|
+
- test/routes_test.rb
|
126
|
+
- test/tags_parser_test.rb
|
127
|
+
- test/test_helper.rb
|
128
|
+
- test/test_suite.rb
|
129
|
+
- test/tweet_maker.rb
|
130
|
+
- test/tweet_maker_test.rb
|
131
|
+
- test/tweet_route_test.rb
|
132
|
+
- test/tweeter_test.rb
|
133
|
+
- test/users_parser_test.rb
|