jsl-osprey 0.0.2 → 0.0.3
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/README.rdoc +62 -3
- metadata +4 -33
- data/Rakefile +0 -42
- data/lib/core_ext/array.rb +0 -8
- data/lib/core_ext/hash.rb +0 -5
- data/lib/osprey/backend/dev_null.rb +0 -21
- data/lib/osprey/backend/filesystem.rb +0 -32
- data/lib/osprey/backend/memcache.rb +0 -35
- data/lib/osprey/backend/memory.rb +0 -22
- data/lib/osprey/result_set.rb +0 -11
- data/lib/osprey/search.rb +0 -73
- data/lib/osprey/tweet.rb +0 -4
- data/lib/osprey.rb +0 -16
- data/spec/fixtures/result_set.yml +0 -197
- data/spec/fixtures/swine_flu1.json +0 -1
- data/spec/fixtures/swine_flu2.json +0 -1
- data/spec/osprey/backend/dev_null_spec.rb +0 -35
- data/spec/osprey/backend/filesystem_spec.rb +0 -23
- data/spec/osprey/backend/memcache_spec.rb +0 -25
- data/spec/osprey/backend/memory_spec.rb +0 -14
- data/spec/osprey/result_set_spec.rb +0 -15
- data/spec/osprey/search_spec.rb +0 -68
- data/spec/osprey_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -19
data/README.rdoc
CHANGED
|
@@ -1,16 +1,75 @@
|
|
|
1
1
|
= Description
|
|
2
2
|
|
|
3
|
-
Osprey is a tool for
|
|
3
|
+
Osprey is a tool for efficiently grabbing the latest Twitter tweets over the "search" API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The premise behind Osprey is that your application shouldn't have to worry about sorting out new tweets from ones that
|
|
6
|
+
you've seen. Osprey takes care of these details, allowing your application to focus on more specific logic about what
|
|
7
|
+
to do when a new tweet is discovered. Even if you search on several related terms, Osprey only shows you the new tweets
|
|
8
|
+
by storing the ids of previous tweets in a global pool which can easily be shared among multiple Osprey threads.
|
|
9
|
+
|
|
10
|
+
= Installation
|
|
11
|
+
|
|
12
|
+
sudo gem install osprey
|
|
6
13
|
|
|
7
14
|
= Usage
|
|
8
15
|
|
|
16
|
+
Basic usage of Osprey is simple, and more advanced usage is easily accomodated by the accepted options and the
|
|
17
|
+
ability to write custom backend modules.
|
|
18
|
+
|
|
19
|
+
In more basic cases, you can use Osprey as follows:
|
|
20
|
+
|
|
21
|
+
require 'osprey'
|
|
22
|
+
|
|
9
23
|
results = Osprey::Search.new('swine flu').fetch
|
|
10
24
|
|
|
11
25
|
results.records # Returns all records found as Osprey::Tweet objects
|
|
12
26
|
results.new_records # Returns only the records that you haven't seen in response to the query 'swine flu'
|
|
13
27
|
|
|
28
|
+
Osprey starts to work its magic when you call fetch more than once, either in the current session or after re-
|
|
29
|
+
instantiating the program. Osprey will remember the tweets that it last retrieved and show you a list of new_feeds
|
|
30
|
+
in the response object.
|
|
31
|
+
|
|
32
|
+
= Processing Details
|
|
33
|
+
|
|
34
|
+
Osprey implements a simple but effective algorithm for keeping track of which tweets are new and which have been seen before.
|
|
35
|
+
|
|
36
|
+
First, Osprey keeps track of the tweets retrieved on previous fetches of a given term. We use the last set of
|
|
37
|
+
retrieved results for a given search term in order to construct the next query to Twitter. Basically, we take
|
|
38
|
+
the highest integer ID already retrieved and use this to construct the search URL. When we get the results back,
|
|
39
|
+
we construct the results so that new_records only contains the tweets that we haven't seen before.
|
|
40
|
+
|
|
41
|
+
If the event that no new results are found, we return the previous set of results to the user after marking all
|
|
42
|
+
results as "seen". We then store the previous results (with no records marked as "new") in order to keep the marker
|
|
43
|
+
of the last seen tweet for subsequent requests.
|
|
44
|
+
|
|
45
|
+
Since there is the possibility that another search may have gotten the same tweet, we check each result against
|
|
46
|
+
a global pool of Tweet ids, which we continually truncate so that we can quickly determine new feeds while pushing
|
|
47
|
+
out ids that we probably don't have to remember any more. If the number of stored ids is too much or too little
|
|
48
|
+
for your application, you can easily tune it in the configuration.
|
|
49
|
+
|
|
50
|
+
= Configuration
|
|
51
|
+
|
|
52
|
+
Osprey allows configuration of the backend module used for storage of previous Tweet retrievals, as well as the number
|
|
53
|
+
of previous tweet ids to store so that we can discern new tweets from ones that we've already seen.
|
|
54
|
+
|
|
55
|
+
== Backend module configuration
|
|
56
|
+
|
|
57
|
+
Osprey stores information about previously fetched terms in the backends. You can choose which backend to use through an optional
|
|
58
|
+
options hash after the search term given to the Osprey::Search initializer. By passing options[:backend][:klass], you can specify
|
|
59
|
+
which backend to choose. Currently supported options are Osprey::Backend::Filesystem, Osprey::Backend::Memcache (also works with Tokyo Tyrant)
|
|
60
|
+
Osprey::Backend::Memory (uses a no-configuration Ruby Hash) and Osprey::Backend::DevNull, which doesn't save any information about previously
|
|
61
|
+
fetched tweets.
|
|
62
|
+
|
|
63
|
+
== Tweet id pool configuration
|
|
64
|
+
|
|
65
|
+
Osprey saves ids of previously fetched tweets in the pool so that it can differentiate between new tweets and previously seen tweets, even
|
|
66
|
+
if these tweets came from different search terms. Obviously, if you run enough searches you'll run out of space to store the previously
|
|
67
|
+
fetched ids, and searches will take longer since there is a bigger set of ids through which we need to scan to see if a tweet is new or not.
|
|
68
|
+
|
|
69
|
+
Osprey defaults to saving 10,000 tweet ids, as this is usually enough to allow us to pick out new tweets, and it's small enough so that
|
|
70
|
+
it doesn't take long to see if a particular tweet has been seen before or not. If you like another number better, just set :preserved_tweet_ids
|
|
71
|
+
in the input options to Osprey::Search. Setting this default to 0 will effectively disable Osprey's global memory for last-seen tweets.
|
|
72
|
+
|
|
14
73
|
= Author
|
|
15
74
|
|
|
16
|
-
Justin S. Leitgeb, justin@phq.org
|
|
75
|
+
Justin S. Leitgeb, mailto:justin@phq.org
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jsl-osprey
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Leitgeb
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-05-
|
|
12
|
+
date: 2009-05-05 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|
|
@@ -23,28 +23,6 @@ extra_rdoc_files:
|
|
|
23
23
|
- README.rdoc
|
|
24
24
|
files:
|
|
25
25
|
- README.rdoc
|
|
26
|
-
- Rakefile
|
|
27
|
-
- lib/core_ext/array.rb
|
|
28
|
-
- lib/core_ext/hash.rb
|
|
29
|
-
- lib/osprey.rb
|
|
30
|
-
- lib/osprey/backend/dev_null.rb
|
|
31
|
-
- lib/osprey/backend/filesystem.rb
|
|
32
|
-
- lib/osprey/backend/memcache.rb
|
|
33
|
-
- lib/osprey/backend/memory.rb
|
|
34
|
-
- lib/osprey/result_set.rb
|
|
35
|
-
- lib/osprey/tweet.rb
|
|
36
|
-
- lib/osprey/search.rb
|
|
37
|
-
- spec/fixtures/result_set.yml
|
|
38
|
-
- spec/fixtures/swine_flu1.json
|
|
39
|
-
- spec/fixtures/swine_flu2.json
|
|
40
|
-
- spec/osprey/backend/dev_null_spec.rb
|
|
41
|
-
- spec/osprey/backend/filesystem_spec.rb
|
|
42
|
-
- spec/osprey/backend/memcache_spec.rb
|
|
43
|
-
- spec/osprey/backend/memory_spec.rb
|
|
44
|
-
- spec/osprey/result_set_spec.rb
|
|
45
|
-
- spec/osprey/search_spec.rb
|
|
46
|
-
- spec/osprey_spec.rb
|
|
47
|
-
- spec/spec_helper.rb
|
|
48
26
|
has_rdoc: true
|
|
49
27
|
homepage: http://github.com/jsl/osprey
|
|
50
28
|
post_install_message:
|
|
@@ -71,12 +49,5 @@ rubygems_version: 1.2.0
|
|
|
71
49
|
signing_key:
|
|
72
50
|
specification_version: 2
|
|
73
51
|
summary: A Twitter API that keeps track of tweets you've seen
|
|
74
|
-
test_files:
|
|
75
|
-
|
|
76
|
-
- spec/osprey/backend/filesystem_spec.rb
|
|
77
|
-
- spec/osprey/backend/memcache_spec.rb
|
|
78
|
-
- spec/osprey/backend/memory_spec.rb
|
|
79
|
-
- spec/osprey/result_set_spec.rb
|
|
80
|
-
- spec/osprey/search_spec.rb
|
|
81
|
-
- spec/osprey_spec.rb
|
|
82
|
-
- spec/spec_helper.rb
|
|
52
|
+
test_files: []
|
|
53
|
+
|
data/Rakefile
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'spec'
|
|
3
|
-
|
|
4
|
-
require 'rake'
|
|
5
|
-
require 'spec/rake/spectask'
|
|
6
|
-
require 'rake/rdoctask'
|
|
7
|
-
|
|
8
|
-
require 'lib/osprey'
|
|
9
|
-
|
|
10
|
-
desc 'Test the plugin.'
|
|
11
|
-
Spec::Rake::SpecTask.new(:spec) do |t|
|
|
12
|
-
t.spec_opts = ["--format", "progress", "--colour"]
|
|
13
|
-
t.libs << 'lib'
|
|
14
|
-
t.verbose = true
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
begin
|
|
18
|
-
require 'jeweler'
|
|
19
|
-
Jeweler::Tasks.new do |gemspec|
|
|
20
|
-
gemspec.name = "osprey"
|
|
21
|
-
gemspec.summary = "A Twitter API that keeps track of tweets you've seen"
|
|
22
|
-
gemspec.email = "justin@phq.org"
|
|
23
|
-
gemspec.homepage = "http://github.com/jsl/osprey"
|
|
24
|
-
gemspec.description = "Osprey interfaces with the Twitter search API and keeps track of tweets you've seen"
|
|
25
|
-
gemspec.authors = ["Justin Leitgeb"]
|
|
26
|
-
end
|
|
27
|
-
rescue LoadError
|
|
28
|
-
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
desc "Run all the tests"
|
|
32
|
-
task :default => :spec
|
|
33
|
-
|
|
34
|
-
desc 'Generate documentation'
|
|
35
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
36
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
37
|
-
rdoc.title = 'Osprey'
|
|
38
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
|
39
|
-
rdoc.rdoc_files.include('README')
|
|
40
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
41
|
-
end
|
|
42
|
-
|
data/lib/core_ext/array.rb
DELETED
data/lib/core_ext/hash.rb
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Osprey
|
|
2
|
-
module Backend
|
|
3
|
-
|
|
4
|
-
# Class exists for cases where you don't want Feedzirra to remember what
|
|
5
|
-
# it has fetched. If this backend is selected, user needs to pass arguments
|
|
6
|
-
# in the form of a Feed object to the Reader class to help Feedzirra know when
|
|
7
|
-
# a page hasn't changed, and which feed entries have been updated.
|
|
8
|
-
class DevNull
|
|
9
|
-
|
|
10
|
-
def initialize(options = { })
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def get(url)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def set(url, result)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
require 'md5'
|
|
2
|
-
require 'uri'
|
|
3
|
-
|
|
4
|
-
module Osprey
|
|
5
|
-
module Backend
|
|
6
|
-
class Filesystem
|
|
7
|
-
|
|
8
|
-
DEFAULTS = {
|
|
9
|
-
:path => File.expand_path(File.join(%w[ ~ / .osprey ]))
|
|
10
|
-
} unless defined?(DEFAULTS)
|
|
11
|
-
|
|
12
|
-
def initialize(options = { })
|
|
13
|
-
@options = DEFAULTS.merge(options)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def get(url)
|
|
17
|
-
f = filename_for(url)
|
|
18
|
-
Marshal.load(File.read(f)) if File.exist?(f)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def set(url, result)
|
|
22
|
-
File.open(filename_for(url), 'w') {|f| f.write(Marshal.dump(result)) }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def filename_for(url)
|
|
28
|
-
File.join(@options[:path], MD5.hexdigest(URI.parse(url).normalize.to_s))
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module Osprey
|
|
2
|
-
module Backend
|
|
3
|
-
|
|
4
|
-
# Can be used to set up Memcache, or clients able to speak the Memcache protocol such as
|
|
5
|
-
# Tokyo Tyrant, as a Feedzirra::Backend.
|
|
6
|
-
class Memcache
|
|
7
|
-
DEFAULTS = {
|
|
8
|
-
:server => 'localhost',
|
|
9
|
-
:port => '11211'
|
|
10
|
-
} unless defined?(DEFAULTS)
|
|
11
|
-
|
|
12
|
-
def initialize(options = { })
|
|
13
|
-
@options = DEFAULTS.merge(options)
|
|
14
|
-
@cache = MemCache.new([ @options[:server], @options[:port] ].join(':'), :namespace => 'Osprey')
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def get(url)
|
|
18
|
-
res = @cache.get(key_for(url))
|
|
19
|
-
Marshal.load(res) unless res.nil?
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def set(url, result)
|
|
23
|
-
@cache.set(key_for(url), Marshal.dump(result))
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def key_for(url)
|
|
29
|
-
MD5.hexdigest(URI.parse(url).normalize.to_s)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Osprey
|
|
2
|
-
module Backend
|
|
3
|
-
|
|
4
|
-
# Memory store uses a ruby Hash to store the results of feed fetches.
|
|
5
|
-
# It won't persist after the application exits.
|
|
6
|
-
class Memory
|
|
7
|
-
|
|
8
|
-
def initialize(options = { })
|
|
9
|
-
@store = { }
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def get(url)
|
|
13
|
-
@store[url]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def set(url, result)
|
|
17
|
-
@store[url] = result
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
data/lib/osprey/result_set.rb
DELETED
data/lib/osprey/search.rb
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
module Osprey
|
|
2
|
-
class Search
|
|
3
|
-
attr_reader :term
|
|
4
|
-
|
|
5
|
-
DEFAULTS = {
|
|
6
|
-
:backend => {
|
|
7
|
-
:klass => Osprey::Backend::Memory
|
|
8
|
-
}
|
|
9
|
-
} unless defined?(DEFAULTS)
|
|
10
|
-
|
|
11
|
-
def initialize(term, options = { })
|
|
12
|
-
@term = term
|
|
13
|
-
@options = options.reverse_merge(DEFAULTS)
|
|
14
|
-
@backend = initialize_backend(@options[:backend][:klass])
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def fetch
|
|
18
|
-
res = Curl::Easy.perform(url)
|
|
19
|
-
|
|
20
|
-
if res.response_code == 200
|
|
21
|
-
parse_tweets(res.body_str)
|
|
22
|
-
else
|
|
23
|
-
$stderr.puts "Received invalid twitter response code of #{res.response_code}."
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
# Initializes the on-disk structure that keeps track of the Twitter ids that
|
|
30
|
-
# we've seen. We use a sql lite data store because it handles concurrency
|
|
31
|
-
# for us, which is important if there are multiple threads hitting the data
|
|
32
|
-
# store.
|
|
33
|
-
def initialize_backend(klass)
|
|
34
|
-
klass.new
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Returns an Array of ids for the Tweets in result
|
|
38
|
-
def twitter_ids_from_json_result(json)
|
|
39
|
-
json['results'].map{|r| r['id'].to_i }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def twitter_ids_in(id_list)
|
|
43
|
-
id_list
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def parse_tweets(json_text)
|
|
47
|
-
json = JSON.parse(json_text)
|
|
48
|
-
|
|
49
|
-
res = Osprey::ResultSet.new
|
|
50
|
-
|
|
51
|
-
presults = previous_results
|
|
52
|
-
|
|
53
|
-
json['results'].each do |t|
|
|
54
|
-
new_record = presults.detect{|rec| rec.twitter_id == t['id'] }.nil?
|
|
55
|
-
res << Osprey::Tweet.new(t.merge(:new_record? => new_record, :twitter_id => t['id']))
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
@backend.set(url, res)
|
|
59
|
-
|
|
60
|
-
res
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def previous_results
|
|
64
|
-
@backend.get(url) || [ ]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Returns the Twitter search URL for @term
|
|
68
|
-
def url
|
|
69
|
-
"http://search.twitter.com/search.json?q=#{CGI.escape(@term)}"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
end
|
|
73
|
-
end
|
data/lib/osprey/tweet.rb
DELETED
data/lib/osprey.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'singleton'
|
|
3
|
-
require 'curb'
|
|
4
|
-
require 'CGI'
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'sequel'
|
|
7
|
-
require 'memcache'
|
|
8
|
-
require 'ostruct'
|
|
9
|
-
|
|
10
|
-
lib_dirs = [ 'core_ext', File.join('osprey', 'backend'), 'osprey' ].map do |d|
|
|
11
|
-
File.join(File.dirname(__FILE__), d)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
lib_dirs.each do |d|
|
|
15
|
-
Dir[File.join(d, "*.rb")].each {|file| require file }
|
|
16
|
-
end
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
--- !seq:Osprey::ResultSet
|
|
2
|
-
- !ruby/object:Osprey::Tweet
|
|
3
|
-
table:
|
|
4
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
5
|
-
:from_user_id: 14559662
|
|
6
|
-
:iso_language_code: en
|
|
7
|
-
:new_record?: false
|
|
8
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/189894422/IMG00701_normal.JPG
|
|
9
|
-
:twitter_id: 1701714354
|
|
10
|
-
:text: School is shut down! due to swine flu!! thats a good thing right?
|
|
11
|
-
:created_at: Tue, 05 May 2009 01:28:10 +0000
|
|
12
|
-
:to_user_id:
|
|
13
|
-
:id: 1701714354
|
|
14
|
-
:from_user: moonbrella
|
|
15
|
-
- !ruby/object:Osprey::Tweet
|
|
16
|
-
table:
|
|
17
|
-
:source: "<a href="http://orangatame.com/products/twitterberry/">TwitterBerry</a>"
|
|
18
|
-
:from_user_id: 4513402
|
|
19
|
-
:iso_language_code: en
|
|
20
|
-
:new_record?: false
|
|
21
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/133607145/djeloowel_normal.jpg
|
|
22
|
-
:twitter_id: 1701714238
|
|
23
|
-
:text: Blame it on the flu got u feelin blue, blame it on the swine got u feelin blind, blame it on the mex mex mex mex mex mexicans....
|
|
24
|
-
:created_at: Tue, 05 May 2009 01:28:07 +0000
|
|
25
|
-
:to_user_id:
|
|
26
|
-
:id: 1701714238
|
|
27
|
-
:from_user: DJELOO
|
|
28
|
-
- !ruby/object:Osprey::Tweet
|
|
29
|
-
table:
|
|
30
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
31
|
-
:from_user_id: 14573136
|
|
32
|
-
:new_record?: false
|
|
33
|
-
:profile_image_url: http://static.twitter.com/images/default_profile_normal.png
|
|
34
|
-
:twitter_id: 1701713717
|
|
35
|
-
:text: Swine Flu
|
|
36
|
-
:created_at: Tue, 05 May 2009 01:28:04 +0000
|
|
37
|
-
:to_user_id:
|
|
38
|
-
:id: 1701713717
|
|
39
|
-
:from_user: friendbartrends
|
|
40
|
-
- !ruby/object:Osprey::Tweet
|
|
41
|
-
table:
|
|
42
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
43
|
-
:from_user_id: 15592670
|
|
44
|
-
:iso_language_code: da
|
|
45
|
-
:new_record?: false
|
|
46
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/197468025/images_normal.jpg
|
|
47
|
-
:twitter_id: 1701713665
|
|
48
|
-
:text: Destroying swine flu
|
|
49
|
-
:created_at: Tue, 05 May 2009 01:28:04 +0000
|
|
50
|
-
:to_user_id:
|
|
51
|
-
:id: 1701713665
|
|
52
|
-
:from_user: premierozone
|
|
53
|
-
- !ruby/object:Osprey::Tweet
|
|
54
|
-
table:
|
|
55
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
56
|
-
:from_user_id: 1983836
|
|
57
|
-
:iso_language_code: en
|
|
58
|
-
:new_record?: false
|
|
59
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/61959717/DD_Oaxaca_Flower_normal.jpg
|
|
60
|
-
:twitter_id: 1701712780
|
|
61
|
-
:text: "@M_tm uh, finally, something more disturbing than swine flu..."
|
|
62
|
-
:created_at: Tue, 05 May 2009 01:27:58 +0000
|
|
63
|
-
:to_user_id: 125590
|
|
64
|
-
:to_user: M_tm
|
|
65
|
-
:id: 1701712780
|
|
66
|
-
:from_user: Funchilde
|
|
67
|
-
- !ruby/object:Osprey::Tweet
|
|
68
|
-
table:
|
|
69
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
70
|
-
:from_user_id: 15567837
|
|
71
|
-
:iso_language_code: en
|
|
72
|
-
:new_record?: false
|
|
73
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/197027649/waiting_normal.jpg
|
|
74
|
-
:twitter_id: 1701712037
|
|
75
|
-
:text: Susie gave me a Lysol Hand Sanitizer that says "Protects from Swine Flu" (Haha) for the bracelet.
|
|
76
|
-
:created_at: Tue, 05 May 2009 01:27:53 +0000
|
|
77
|
-
:to_user_id:
|
|
78
|
-
:id: 1701712037
|
|
79
|
-
:from_user: StayPositive_
|
|
80
|
-
- !ruby/object:Osprey::Tweet
|
|
81
|
-
table:
|
|
82
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
83
|
-
:from_user_id: 13123935
|
|
84
|
-
:iso_language_code: eo
|
|
85
|
-
:new_record?: false
|
|
86
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/151854910/20070408041551_nivertia06churras07-01069_normal.jpg
|
|
87
|
-
:twitter_id: 1701711989
|
|
88
|
-
:text: "@danilogentili Swine Flu !!!!!"
|
|
89
|
-
:created_at: Tue, 05 May 2009 01:27:53 +0000
|
|
90
|
-
:to_user_id: 168227
|
|
91
|
-
:to_user: danilogentili
|
|
92
|
-
:id: 1701711989
|
|
93
|
-
:from_user: pannain
|
|
94
|
-
- !ruby/object:Osprey::Tweet
|
|
95
|
-
table:
|
|
96
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
97
|
-
:from_user_id: 1580999
|
|
98
|
-
:iso_language_code: en
|
|
99
|
-
:new_record?: false
|
|
100
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/59851479/n31700687_7014_normal.jpg
|
|
101
|
-
:twitter_id: 1701711830
|
|
102
|
-
:text: realized that after swine flu we'll get Bear pox, followed by beaver fever, and ending with Mongoose Malaria.... Be on your toes!
|
|
103
|
-
:created_at: Tue, 05 May 2009 01:27:52 +0000
|
|
104
|
-
:to_user_id:
|
|
105
|
-
:id: 1701711830
|
|
106
|
-
:from_user: BubbaStoned85
|
|
107
|
-
- !ruby/object:Osprey::Tweet
|
|
108
|
-
table:
|
|
109
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
110
|
-
:from_user_id: 166576
|
|
111
|
-
:iso_language_code: en
|
|
112
|
-
:new_record?: false
|
|
113
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/88556721/profpic2_lg_normal.png
|
|
114
|
-
:twitter_id: 1701711644
|
|
115
|
-
:text: + "90 people get the swine flu and everyone wants to wear a face mask. Millions get AIDS and nobody wears a condom. Go figure."
|
|
116
|
-
:created_at: Tue, 05 May 2009 01:27:51 +0000
|
|
117
|
-
:to_user_id:
|
|
118
|
-
:id: 1701711644
|
|
119
|
-
:from_user: gemmerzz
|
|
120
|
-
- !ruby/object:Osprey::Tweet
|
|
121
|
-
table:
|
|
122
|
-
:source: "<a href="http://twitterfeed.com">twitterfeed</a>"
|
|
123
|
-
:from_user_id: 14562545
|
|
124
|
-
:iso_language_code: en
|
|
125
|
-
:new_record?: false
|
|
126
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/189807824/1_normal.jpg
|
|
127
|
-
:twitter_id: 1701711527
|
|
128
|
-
:text: "#swineflu 6 More Swine Flu Cases Confirmed on LI - LongIslandPress.com http://ad.vu/bir4"
|
|
129
|
-
:created_at: Tue, 05 May 2009 01:27:50 +0000
|
|
130
|
-
:to_user_id:
|
|
131
|
-
:id: 1701711527
|
|
132
|
-
:from_user: News_SwineFlu
|
|
133
|
-
- !ruby/object:Osprey::Tweet
|
|
134
|
-
table:
|
|
135
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
136
|
-
:from_user_id: 8288437
|
|
137
|
-
:iso_language_code: en
|
|
138
|
-
:new_record?: false
|
|
139
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/193624367/100_1084_normal.jpg
|
|
140
|
-
:twitter_id: 1701710705
|
|
141
|
-
:text: That darn Swine Flu is getting a tad close for comfort! A school about twenty minutes from mine closed down for a few days tonight!
|
|
142
|
-
:created_at: Tue, 05 May 2009 01:27:45 +0000
|
|
143
|
-
:to_user_id:
|
|
144
|
-
:id: 1701710705
|
|
145
|
-
:from_user: tylergraves2009
|
|
146
|
-
- !ruby/object:Osprey::Tweet
|
|
147
|
-
table:
|
|
148
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
149
|
-
:from_user_id: 3617869
|
|
150
|
-
:iso_language_code: en
|
|
151
|
-
:new_record?: true
|
|
152
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/71116723/jojobo_normal.jpg
|
|
153
|
-
:twitter_id: 1701710268
|
|
154
|
-
:text: "Explaining to the children why they don't need to be terrified of swine flu, but why they really do need to wash their hands. #swineflu"
|
|
155
|
-
:created_at: Tue, 05 May 2009 01:27:42 +0000
|
|
156
|
-
:to_user_id:
|
|
157
|
-
:id: 1701710268
|
|
158
|
-
:from_user: jojobo
|
|
159
|
-
- !ruby/object:Osprey::Tweet
|
|
160
|
-
table:
|
|
161
|
-
:source: "<a href="http://twitter.com/">web</a>"
|
|
162
|
-
:from_user_id: 3362361
|
|
163
|
-
:iso_language_code: en
|
|
164
|
-
:new_record?: true
|
|
165
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/76497810/picture_normal.jpg
|
|
166
|
-
:twitter_id: 1701709964
|
|
167
|
-
:text: Another day locked up with Swine Flu outside. Just went to HomeDepot and more then 50 percent of clients have masks there.
|
|
168
|
-
:created_at: Tue, 05 May 2009 01:27:40 +0000
|
|
169
|
-
:to_user_id:
|
|
170
|
-
:id: 1701709964
|
|
171
|
-
:from_user: dennisvdheijden
|
|
172
|
-
- !ruby/object:Osprey::Tweet
|
|
173
|
-
table:
|
|
174
|
-
:source: "<a href="http://twitterfox.net/">TwitterFox</a>"
|
|
175
|
-
:from_user_id: 643746
|
|
176
|
-
:iso_language_code: nl
|
|
177
|
-
:new_record?: true
|
|
178
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/79399738/cami1_normal.jpg
|
|
179
|
-
:twitter_id: 1701709832
|
|
180
|
-
:text: "RT: @KYLking: Byron Center High School students celebrate 'swine break' after flu closes school for week http://tinyurl.com/d2b3yh"
|
|
181
|
-
:created_at: Tue, 05 May 2009 01:27:39 +0000
|
|
182
|
-
:to_user_id:
|
|
183
|
-
:id: 1701709832
|
|
184
|
-
:from_user: creister
|
|
185
|
-
- !ruby/object:Osprey::Tweet
|
|
186
|
-
table:
|
|
187
|
-
:source: "<a href="http://iconfactory.com/software/twitterrific">twitterrific</a>"
|
|
188
|
-
:from_user_id: 7400045
|
|
189
|
-
:iso_language_code: en
|
|
190
|
-
:new_record?: true
|
|
191
|
-
:profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/150699579/for_my_baby_normal.jpg
|
|
192
|
-
:twitter_id: 1701709797
|
|
193
|
-
:text: I know I said I was going to sleep but who sleeps when you can twitter Itslike an epidemic this twitter stuff it spread like the swine flu
|
|
194
|
-
:created_at: Tue, 05 May 2009 01:27:39 +0000
|
|
195
|
-
:to_user_id:
|
|
196
|
-
:id: 1701709797
|
|
197
|
-
:from_user: chefjay1121
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"results":[{"text":"RT @nicfish: Tracking Swine Flu with Microsoft Virtual Earth and Live Search http:\/\/bit.ly\/YqdDC --> sweet!","to_user_id":null,"from_user":"tameraclark","id":1701715308,"from_user_id":386286,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/188156012\/eye2_normal.jpg","created_at":"Tue, 05 May 2009 01:28:14 +0000"},{"text":"@keepsgettinbetr when did i worry about the swine flu","to_user_id":9477722,"to_user":"keepsgettinbetr","from_user":"Bayleeee","id":1701714956,"from_user_id":7978237,"iso_language_code":"en","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Tue, 05 May 2009 01:28:12 +0000"},{"text":"RT @TelegraphNews: Swine flu: Mexico starts to ease virus restrictions http:\/\/tinyurl.com\/db6jff","to_user_id":null,"from_user":"lili_one","id":1701714620,"from_user_id":4481131,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/181901124\/31-01-07_1330_normal.jpg","created_at":"Tue, 05 May 2009 01:28:10 +0000"},{"text":"Up to the minute swine flu origins: the visual explanation!\nRT @tweetmeme Coconut Chutney: When pigs fly http:\/\/tinyurl.com\/d8cobj","to_user_id":null,"from_user":"hiddenground","id":1701714439,"from_user_id":4158379,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66627032\/frau-freide_normal.jpg","created_at":"Tue, 05 May 2009 01:28:09 +0000"},{"text":"School is shut down! due to swine flu!! thats a good thing right?","to_user_id":null,"from_user":"moonbrella","id":1701714354,"from_user_id":14559662,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/189894422\/IMG00701_normal.JPG","created_at":"Tue, 05 May 2009 01:28:10 +0000"},{"text":"Blame it on the flu got u feelin blue, blame it on the swine got u feelin blind, blame it on the mex mex mex mex mex mexicans....","to_user_id":null,"from_user":"DJELOO","id":1701714238,"from_user_id":4513402,"iso_language_code":"en","source":"<a href="http:\/\/orangatame.com\/products\/twitterberry\/">TwitterBerry<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/133607145\/djeloowel_normal.jpg","created_at":"Tue, 05 May 2009 01:28:07 +0000"},{"text":"Swine Flu","to_user_id":null,"from_user":"friendbartrends","id":1701713717,"from_user_id":14573136,"source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Tue, 05 May 2009 01:28:04 +0000"},{"text":"Destroying swine flu","to_user_id":null,"from_user":"premierozone","id":1701713665,"from_user_id":15592670,"iso_language_code":"da","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/197468025\/images_normal.jpg","created_at":"Tue, 05 May 2009 01:28:04 +0000"},{"text":"@M_tm uh, finally, something more disturbing than swine flu...","to_user_id":125590,"to_user":"M_tm","from_user":"Funchilde","id":1701712780,"from_user_id":1983836,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/61959717\/DD_Oaxaca_Flower_normal.jpg","created_at":"Tue, 05 May 2009 01:27:58 +0000"},{"text":"Susie gave me a Lysol Hand Sanitizer that says "Protects from Swine Flu" (Haha) for the bracelet.","to_user_id":null,"from_user":"StayPositive_","id":1701712037,"from_user_id":15567837,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/197027649\/waiting_normal.jpg","created_at":"Tue, 05 May 2009 01:27:53 +0000"},{"text":"@danilogentili Swine Flu !!!!!","to_user_id":168227,"to_user":"danilogentili","from_user":"pannain","id":1701711989,"from_user_id":13123935,"iso_language_code":"eo","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/151854910\/20070408041551_nivertia06churras07-01069_normal.jpg","created_at":"Tue, 05 May 2009 01:27:53 +0000"},{"text":"realized that after swine flu we'll get Bear pox, followed by beaver fever, and ending with Mongoose Malaria.... Be on your toes!","to_user_id":null,"from_user":"BubbaStoned85","id":1701711830,"from_user_id":1580999,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59851479\/n31700687_7014_normal.jpg","created_at":"Tue, 05 May 2009 01:27:52 +0000"},{"text":"+ "90 people get the swine flu and everyone wants to wear a face mask. Millions get AIDS and nobody wears a condom. Go figure."","to_user_id":null,"from_user":"gemmerzz","id":1701711644,"from_user_id":166576,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/88556721\/profpic2_lg_normal.png","created_at":"Tue, 05 May 2009 01:27:51 +0000"},{"text":"#swineflu 6 More Swine Flu Cases Confirmed on LI - LongIslandPress.com http:\/\/ad.vu\/bir4","to_user_id":null,"from_user":"News_SwineFlu","id":1701711527,"from_user_id":14562545,"iso_language_code":"en","source":"<a href="http:\/\/twitterfeed.com">twitterfeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/189807824\/1_normal.jpg","created_at":"Tue, 05 May 2009 01:27:50 +0000"},{"text":"That darn Swine Flu is getting a tad close for comfort! A school about twenty minutes from mine closed down for a few days tonight!","to_user_id":null,"from_user":"tylergraves2009","id":1701710705,"from_user_id":8288437,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/193624367\/100_1084_normal.jpg","created_at":"Tue, 05 May 2009 01:27:45 +0000"}],"since_id":0,"max_id":1701715308,"refresh_url":"?since_id=1701715308&q=swine+flu","results_per_page":15,"next_page":"?page=2&max_id=1701715308&q=swine+flu","completed_in":0.032499,"page":1,"query":"swine+flu"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"results":[{"text":"School is shut down! due to swine flu!! thats a good thing right?","to_user_id":null,"from_user":"moonbrella","id":1701714354,"from_user_id":14559662,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/189894422\/IMG00701_normal.JPG","created_at":"Tue, 05 May 2009 01:28:10 +0000"},{"text":"Blame it on the flu got u feelin blue, blame it on the swine got u feelin blind, blame it on the mex mex mex mex mex mexicans....","to_user_id":null,"from_user":"DJELOO","id":1701714238,"from_user_id":4513402,"iso_language_code":"en","source":"<a href="http:\/\/orangatame.com\/products\/twitterberry\/">TwitterBerry<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/133607145\/djeloowel_normal.jpg","created_at":"Tue, 05 May 2009 01:28:07 +0000"},{"text":"Swine Flu","to_user_id":null,"from_user":"friendbartrends","id":1701713717,"from_user_id":14573136,"source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Tue, 05 May 2009 01:28:04 +0000"},{"text":"Destroying swine flu","to_user_id":null,"from_user":"premierozone","id":1701713665,"from_user_id":15592670,"iso_language_code":"da","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/197468025\/images_normal.jpg","created_at":"Tue, 05 May 2009 01:28:04 +0000"},{"text":"@M_tm uh, finally, something more disturbing than swine flu...","to_user_id":125590,"to_user":"M_tm","from_user":"Funchilde","id":1701712780,"from_user_id":1983836,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/61959717\/DD_Oaxaca_Flower_normal.jpg","created_at":"Tue, 05 May 2009 01:27:58 +0000"},{"text":"Susie gave me a Lysol Hand Sanitizer that says "Protects from Swine Flu" (Haha) for the bracelet.","to_user_id":null,"from_user":"StayPositive_","id":1701712037,"from_user_id":15567837,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/197027649\/waiting_normal.jpg","created_at":"Tue, 05 May 2009 01:27:53 +0000"},{"text":"@danilogentili Swine Flu !!!!!","to_user_id":168227,"to_user":"danilogentili","from_user":"pannain","id":1701711989,"from_user_id":13123935,"iso_language_code":"eo","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/151854910\/20070408041551_nivertia06churras07-01069_normal.jpg","created_at":"Tue, 05 May 2009 01:27:53 +0000"},{"text":"realized that after swine flu we'll get Bear pox, followed by beaver fever, and ending with Mongoose Malaria.... Be on your toes!","to_user_id":null,"from_user":"BubbaStoned85","id":1701711830,"from_user_id":1580999,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59851479\/n31700687_7014_normal.jpg","created_at":"Tue, 05 May 2009 01:27:52 +0000"},{"text":"+ "90 people get the swine flu and everyone wants to wear a face mask. Millions get AIDS and nobody wears a condom. Go figure."","to_user_id":null,"from_user":"gemmerzz","id":1701711644,"from_user_id":166576,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/88556721\/profpic2_lg_normal.png","created_at":"Tue, 05 May 2009 01:27:51 +0000"},{"text":"#swineflu 6 More Swine Flu Cases Confirmed on LI - LongIslandPress.com http:\/\/ad.vu\/bir4","to_user_id":null,"from_user":"News_SwineFlu","id":1701711527,"from_user_id":14562545,"iso_language_code":"en","source":"<a href="http:\/\/twitterfeed.com">twitterfeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/189807824\/1_normal.jpg","created_at":"Tue, 05 May 2009 01:27:50 +0000"},{"text":"That darn Swine Flu is getting a tad close for comfort! A school about twenty minutes from mine closed down for a few days tonight!","to_user_id":null,"from_user":"tylergraves2009","id":1701710705,"from_user_id":8288437,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/193624367\/100_1084_normal.jpg","created_at":"Tue, 05 May 2009 01:27:45 +0000"},{"text":"Explaining to the children why they don't need to be terrified of swine flu, but why they really do need to wash their hands. #swineflu","to_user_id":null,"from_user":"jojobo","id":1701710268,"from_user_id":3617869,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/71116723\/jojobo_normal.jpg","created_at":"Tue, 05 May 2009 01:27:42 +0000"},{"text":"Another day locked up with Swine Flu outside. Just went to HomeDepot and more then 50 percent of clients have masks there.","to_user_id":null,"from_user":"dennisvdheijden","id":1701709964,"from_user_id":3362361,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/76497810\/picture_normal.jpg","created_at":"Tue, 05 May 2009 01:27:40 +0000"},{"text":"RT: @KYLking: Byron Center High School students celebrate 'swine break' after flu closes school for week http:\/\/tinyurl.com\/d2b3yh","to_user_id":null,"from_user":"creister","id":1701709832,"from_user_id":643746,"iso_language_code":"nl","source":"<a href="http:\/\/twitterfox.net\/">TwitterFox<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/79399738\/cami1_normal.jpg","created_at":"Tue, 05 May 2009 01:27:39 +0000"},{"text":"I know I said I was going to sleep but who sleeps when you can twitter Itslike an epidemic this twitter stuff it spread like the swine flu","to_user_id":null,"from_user":"chefjay1121","id":1701709797,"from_user_id":7400045,"iso_language_code":"en","source":"<a href="http:\/\/iconfactory.com\/software\/twitterrific">twitterrific<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/150699579\/for_my_baby_normal.jpg","created_at":"Tue, 05 May 2009 01:27:39 +0000"}],"since_id":0,"max_id":1701714354,"refresh_url":"?since_id=1701714354&q=swine+flu","results_per_page":15,"next_page":"?page=2&max_id=1701714354&q=swine+flu","completed_in":0.023306,"page":1,"query":"swine+flu"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
|
2
|
-
|
|
3
|
-
describe Osprey::Backend::DevNull do
|
|
4
|
-
before do
|
|
5
|
-
@backend = Osprey::Backend::DevNull.new
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it_should_behave_like "all backends"
|
|
9
|
-
|
|
10
|
-
it "should initialize properly" do
|
|
11
|
-
Osprey::Backend::DevNull.new
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe "#set" do
|
|
15
|
-
it "should accept two arguments" do
|
|
16
|
-
lambda {
|
|
17
|
-
@backend.set('foo', 'nothing')
|
|
18
|
-
}.should_not raise_error
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe "#get" do
|
|
23
|
-
it "should accept one argument" do
|
|
24
|
-
lambda {
|
|
25
|
-
@backend.get('foo')
|
|
26
|
-
}.should_not raise_error
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "should return nil even after something is set" do
|
|
30
|
-
@backend.set('junk', 'something')
|
|
31
|
-
@backend.get('junk').should be_nil
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
|
2
|
-
|
|
3
|
-
describe Osprey::Backend::Filesystem do
|
|
4
|
-
before do
|
|
5
|
-
@backend = Osprey::Backend::Filesystem.new({:path => '/tmp'})
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it_should_behave_like "all backends"
|
|
9
|
-
|
|
10
|
-
it "should accept a Hash of options for inialization" do
|
|
11
|
-
Osprey::Backend::Filesystem.new({:path => '/tmp'})
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe "#filename_for" do
|
|
15
|
-
it "should default to the users' home path plus the MD5 of the normalized URL" do
|
|
16
|
-
MD5.expects(:hexdigest).returns('bah')
|
|
17
|
-
uri = mock('uri')
|
|
18
|
-
uri.expects(:normalize).returns('foo')
|
|
19
|
-
URI.expects(:parse).returns(uri)
|
|
20
|
-
Osprey::Backend::Filesystem.new({:path => '/tmp'}).__send__(:filename_for, 'hey').should == '/tmp/bah'
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
|
2
|
-
|
|
3
|
-
describe Osprey::Backend::Memcache do
|
|
4
|
-
before do
|
|
5
|
-
@backend = Osprey::Backend::Memcache.new({:server => 'localhost', :port => 11211})
|
|
6
|
-
@cache = mock('cache')
|
|
7
|
-
@backend.instance_variable_set(:@cache, @cache)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it_should_behave_like "all backends"
|
|
11
|
-
|
|
12
|
-
describe "#get" do
|
|
13
|
-
it "should call #get on the cache" do
|
|
14
|
-
@cache.expects(:get)
|
|
15
|
-
@backend.get('foo')
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
describe "#set" do
|
|
20
|
-
it "should call #set on the cache" do
|
|
21
|
-
@cache.expects(:set)
|
|
22
|
-
@backend.set('foo', 'hey')
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
|
2
|
-
|
|
3
|
-
describe Osprey::Backend::Memory do
|
|
4
|
-
before do
|
|
5
|
-
@backend = Osprey::Backend::Memory.new
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it_should_behave_like "all backends"
|
|
9
|
-
|
|
10
|
-
it "should initialize properly" do
|
|
11
|
-
Osprey::Backend::Memory.new
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
|
|
2
|
-
|
|
3
|
-
describe Osprey::ResultSet do
|
|
4
|
-
before do
|
|
5
|
-
@rs = YAML.load_file(File.join(File.dirname(__FILE__), %w[.. fixtures result_set.yml]))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it "should return 4 results for #new_records" do
|
|
9
|
-
@rs.new_records.size.should == 4
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it "should return 15 results for #records" do
|
|
13
|
-
@rs.records.size.should == 15
|
|
14
|
-
end
|
|
15
|
-
end
|
data/spec/osprey/search_spec.rb
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
|
|
2
|
-
|
|
3
|
-
describe Osprey::Search do
|
|
4
|
-
describe "initialization" do
|
|
5
|
-
it "should initialize without error" do
|
|
6
|
-
Osprey::Search.new('bar')
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
it "should create a new instance of the default backend" do
|
|
10
|
-
Osprey::Search.new('bar').instance_variable_get(:@backend).should be_a(Osprey::Backend::Memory)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "should set the attr accessor for the term" do
|
|
15
|
-
tr = Osprey::Search.new('foo')
|
|
16
|
-
tr.term.should == 'foo'
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
describe "#fetch" do
|
|
20
|
-
before do
|
|
21
|
-
@tr = Osprey::Search.new('swine flu')
|
|
22
|
-
@curl = mock('curl')
|
|
23
|
-
@curl.expects(:response_code).returns(200)
|
|
24
|
-
@swine_flu_json = File.read(File.join(File.dirname(__FILE__), %w[.. fixtures swine_flu1.json]))
|
|
25
|
-
@curl.expects(:body_str).returns(@swine_flu_json)
|
|
26
|
-
Curl::Easy.expects(:perform).with('http://search.twitter.com/search.json?q=swine+flu').returns(@curl)
|
|
27
|
-
@results = @tr.fetch
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe "on the initial request of a term" do
|
|
31
|
-
it "should return a Osprey::ResultSet" do
|
|
32
|
-
@results.should be_a(Osprey::ResultSet)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "should contain 15 results" do
|
|
36
|
-
@results.size.should == 15
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "should contain all Osprey::Tweet items" do
|
|
40
|
-
@results.each{|t| t.should be_a(Osprey::Tweet) }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it "should have all results respond affirmatively to new_record?" do
|
|
44
|
-
@results.each{|t| t.new_record?.should be_true}
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
describe "when there are existing results for a term" do
|
|
49
|
-
before do
|
|
50
|
-
@curl.expects(:response_code).returns(200)
|
|
51
|
-
|
|
52
|
-
@swine_flu_json = File.read(File.join(File.dirname(__FILE__), %w[.. fixtures swine_flu2.json]))
|
|
53
|
-
@curl.expects(:body_str).returns(@swine_flu_json)
|
|
54
|
-
Curl::Easy.expects(:perform).with('http://search.twitter.com/search.json?q=swine+flu').returns(@curl)
|
|
55
|
-
@results = @tr.fetch
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "should have 4 records that are not marked as new" do
|
|
59
|
-
@results.select{|r| r.new_record? }.size.should == 4
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
describe "when feed ids are listed in the pool" do
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
end
|
|
68
|
-
end
|
data/spec/osprey_spec.rb
DELETED
data/spec/spec_helper.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'mocha'
|
|
3
|
-
require 'spec'
|
|
4
|
-
|
|
5
|
-
require File.join(File.dirname(__FILE__), %w[.. lib osprey])
|
|
6
|
-
|
|
7
|
-
Spec::Runner.configure do |config|
|
|
8
|
-
config.mock_with(:mocha)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
shared_examples_for "all backends" do
|
|
12
|
-
it "should respond to #get" do
|
|
13
|
-
@backend.should respond_to(:get)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "should respond to #set" do
|
|
17
|
-
@backend.should respond_to(:set)
|
|
18
|
-
end
|
|
19
|
-
end
|