crags 1.6.0 → 2.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.
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Item do
4
+ before do
5
+ elem = stub
6
+ elem.stub!(:title).and_return("title!")
7
+ elem.stub!(:url).and_return("url!")
8
+ elem.stub!(:date).and_return("date!")
9
+ @item = Item.new(elem)
10
+ end
11
+
12
+ it "has a title reader" do
13
+ @item.title.should == "title!"
14
+ end
15
+
16
+ it "has a url reader" do
17
+ @item.url.should == "url!"
18
+ end
19
+
20
+ it "has a date reader" do
21
+ @item.date.should == "date!"
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Location do
4
+ before do
5
+ @loc = Location.new("domain.com")
6
+ end
7
+
8
+ it "has a domain reader" do
9
+ @loc.domain.should == "domain.com"
10
+ end
11
+
12
+ it "has a url generated form the domain" do
13
+ @loc.url.should == "http://domain.com"
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Search::Country do
4
+ before do
5
+ Crags::Config.stub!(:defaults).and_return({:country => 'heya', :interval => 200})
6
+ @default = Search::Country.new
7
+ @custom = Search::Country.new({:country => 'gabba', :interval => 10})
8
+ end
9
+
10
+ it "has config default country" do
11
+ @default.country.should == "heya"
12
+ end
13
+
14
+ it "has config default interval" do
15
+ @default.interval.should == 200
16
+ end
17
+
18
+ it "has custom country" do
19
+ @custom.country.should == "gabba"
20
+ end
21
+
22
+ it "has config default interval" do
23
+ @custom.interval.should == 10
24
+ end
25
+
26
+ it "delegates locations to country" do
27
+ @default.country.should_receive(:locations).and_return("locations")
28
+ @default.locations.should == "locations"
29
+ end
30
+
31
+ describe "with location searches" do
32
+ before do
33
+ @search = stub
34
+ @search.stub!(:items)
35
+ Search::Location.stub!(:new).and_return(@search)
36
+ @locations = ["loc1", "loc2"]
37
+ @custom.stub!(:sleep)
38
+ end
39
+
40
+ it "calls sleep with interval for each location" do
41
+ @custom.stub!(:locations).and_return(@locations)
42
+ @custom.should_receive(:sleep).with(10).twice
43
+ @custom.items
44
+ end
45
+
46
+ it "creates a new search for each location" do
47
+ Search::Location.should_receive(:new).twice.and_return(@search)
48
+ @custom.stub!(:locations).and_return(@locations)
49
+ @custom.items
50
+ end
51
+
52
+ it "performs the search for each location" do
53
+ @search.should_receive(:items).twice
54
+ @custom.stub!(:locations).and_return(@locations)
55
+ @custom.items
56
+ end
57
+
58
+ it "flattens the search results" do
59
+ collect = mock
60
+ collect.should_receive(:flatten).and_return("flat!")
61
+ locations = stub
62
+ locations.stub!(:collect).and_return(collect)
63
+ @custom.stub!(:locations).and_return(locations)
64
+ @custom.items.should == "flat!"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Search::Location do
4
+ before do
5
+ @default_loc = Crags::Location.new("default.domain.com")
6
+ @default_cat = Crags::Category.new('for sale', 'sss/')
7
+ @custom_loc = Crags::Location.new("custom.domain.com")
8
+ Crags::Config.stub!(:defaults).and_return({
9
+ :keyword => 'bicycle',
10
+ :location => @default_loc,
11
+ :category => @default_cat
12
+ })
13
+ @default = Search::Location.new
14
+ @custom = Search::Location.new({:location => @custom_loc})
15
+ end
16
+
17
+ it "has config default location" do
18
+ @default.location.should == @default_loc
19
+ end
20
+
21
+ it "has custom country" do
22
+ @custom.location.should == @custom_loc
23
+ end
24
+
25
+ it "generate a url based on location, category and keyword" do
26
+ @default.stub!(:url_encode).with('bicycle').and_return('bicycle')
27
+ @default.url.should == "#{@default_loc.url}/search#{@default_cat.url}?query=bicycle"
28
+ end
29
+
30
+ it "fetch the doc at the url with an rss format" do
31
+ @default.stub!(:url).and_return("url")
32
+ @default.should_receive(:fetch_doc).with("url&format=rss").and_return('doc')
33
+ @default.doc.should == 'doc'
34
+ end
35
+
36
+ describe "with a doc" do
37
+ before do
38
+ @doc = mock
39
+ @items = ["item"]
40
+ @doc.stub!(:search).and_return(@items)
41
+ @default.stub!(:doc).and_return(@doc)
42
+ Item.stub!(:new).and_return("crags_item")
43
+ end
44
+
45
+ it "gets all items from the doc" do
46
+ @doc.should_receive(:search).with("item").and_return(@items)
47
+ @default.items
48
+ end
49
+
50
+ it "creates a new crags item for each doc item" do
51
+ Item.should_receive(:new).with("item").and_return("crags_item")
52
+ @default.items
53
+ end
54
+
55
+ it "collects all created items" do
56
+ @default.items.should == ["crags_item"]
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Search::Search do
4
+ before do
5
+ Crags::Config.stub!(:defaults).and_return({:keyword => 'cribz', :category => 'cribcat'})
6
+ @default_obj = Search::Search.new
7
+ @custom_obj = Search::Search.new(:keyword => 'zaks', :category => 'catz')
8
+ end
9
+
10
+ it "has a custom keyword" do
11
+ @custom_obj.keyword.should == "zaks"
12
+ end
13
+
14
+ it "has a custom category" do
15
+ @custom_obj.category.should == "catz"
16
+ end
17
+
18
+ it "has a custom keyword" do
19
+ @default_obj.keyword.should == "cribz"
20
+ end
21
+
22
+ it "has a custom category" do
23
+ @default_obj.category.should == "cribcat"
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hpricot::Elem do
4
+ before do
5
+ @elem = Hpricot::Elem.new("<omg></omg>")
6
+ end
7
+
8
+ it "uses the inner_text of title element for title" do
9
+ title = stub
10
+ title.stub!(:inner_text).and_return("title!")
11
+ @elem.stub!(:at).with("title").and_return(title)
12
+ @elem.title.should == "title!"
13
+ end
14
+
15
+ it "rdf:about attribute for the url" do
16
+ @elem.stub!(:[]).with("rdf:about").and_return("url!")
17
+ @elem.url.should == "url!"
18
+ end
19
+
20
+ it "uses the inner_text of the dc:date element for date_str" do
21
+ dc_date = stub
22
+ dc_date.stub!(:inner_text).and_return("date_str!")
23
+ @elem.stub!(:at).with("dc:date").and_return(dc_date)
24
+ @elem.date_str.should == "date_str!"
25
+ end
26
+
27
+ it "parses date_str to create a real date" do
28
+ DateTime.should_receive(:parse).with("date_str!").and_return("date!")
29
+ @elem.stub!(:date_str).and_return("date_str!")
30
+ @elem.date.should == "date!"
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ it "removes http:// and trailing /" do
5
+ url = "http://omg/"
6
+ url.strip_http.should == "omg"
7
+ end
8
+
9
+ it "removes http:// when there is no trailing slash" do
10
+ url = "http://omg"
11
+ url.strip_http.should == "omg"
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require(:default, :test)
4
+ require 'crags'
5
+ include Crags
metadata CHANGED
@@ -3,10 +3,10 @@ name: crags
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 1
7
- - 6
6
+ - 2
8
7
  - 0
9
- version: 1.6.0
8
+ - 0
9
+ version: 2.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Justin Marney
@@ -14,10 +14,33 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-14 00:00:00 -04:00
17
+ date: 2010-07-26 00:00:00 -04:00
18
18
  default_executable:
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: curb
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: hpricot
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
21
44
  description: A library to help search across multiple craigslist locations.
22
45
  email: gotascii@gmail.com
23
46
  executables: []
@@ -29,21 +52,34 @@ extra_rdoc_files:
29
52
  - README.rdoc
30
53
  files:
31
54
  - .gitignore
55
+ - Gemfile
32
56
  - LICENSE
33
57
  - README.rdoc
34
58
  - Rakefile
35
59
  - VERSION
36
60
  - crags.gemspec
37
61
  - lib/crags.rb
38
- - lib/crags/fetch.rb
39
- - lib/crags/proxy.rb
40
- - lib/crags/runner.rb
41
- - lib/crags/searcher.rb
42
- - test/crags/fetch_test.rb
43
- - test/crags/proxy_test.rb
44
- - test/crags/runner_test.rb
45
- - test/crags/searcher_test.rb
46
- - test/test_helper.rb
62
+ - lib/crags/category.rb
63
+ - lib/crags/country.rb
64
+ - lib/crags/fetcher.rb
65
+ - lib/crags/item.rb
66
+ - lib/crags/location.rb
67
+ - lib/crags/search/country.rb
68
+ - lib/crags/search/location.rb
69
+ - lib/crags/search/search.rb
70
+ - lib/ext/hpricot/elem.rb
71
+ - lib/ext/string.rb
72
+ - spec/crags/category_spec.rb
73
+ - spec/crags/country_spec.rb
74
+ - spec/crags/fetcher_spec.rb
75
+ - spec/crags/item_spec.rb
76
+ - spec/crags/location_spec.rb
77
+ - spec/crags/search/country_spec.rb
78
+ - spec/crags/search/location_spec.rb
79
+ - spec/crags/search/search_spec.rb
80
+ - spec/ext/hpricot/elem_spec.rb
81
+ - spec/ext/string_spec.rb
82
+ - spec/spec_helper.rb
47
83
  has_rdoc: true
48
84
  homepage: http://github.com/gotascii/crags
49
85
  licenses: []
@@ -75,8 +111,14 @@ signing_key:
75
111
  specification_version: 3
76
112
  summary: A library to help search across multiple craigslist locations.
77
113
  test_files:
78
- - test/crags/fetch_test.rb
79
- - test/crags/proxy_test.rb
80
- - test/crags/runner_test.rb
81
- - test/crags/searcher_test.rb
82
- - test/test_helper.rb
114
+ - spec/crags/category_spec.rb
115
+ - spec/crags/country_spec.rb
116
+ - spec/crags/fetcher_spec.rb
117
+ - spec/crags/item_spec.rb
118
+ - spec/crags/location_spec.rb
119
+ - spec/crags/search/country_spec.rb
120
+ - spec/crags/search/location_spec.rb
121
+ - spec/crags/search/search_spec.rb
122
+ - spec/ext/hpricot/elem_spec.rb
123
+ - spec/ext/string_spec.rb
124
+ - spec/spec_helper.rb
data/lib/crags/proxy.rb DELETED
@@ -1,21 +0,0 @@
1
- module Crags
2
- module Proxy
3
- include Fetch
4
-
5
- def lists
6
- ["http://www.proxy4free.com/page1.html","http://www.proxy4free.com/page3.html"]
7
- end
8
-
9
- def fetch_lists
10
- lists.collect {|url| fetch_html(url)}
11
- end
12
-
13
- def scan(text)
14
- text.scan(/\d+\.\d+\.\d+\.\d+/)
15
- end
16
-
17
- def proxies
18
- fetch_lists.collect{|html|scan(html)}.flatten.uniq
19
- end
20
- end
21
- end
data/lib/crags/runner.rb DELETED
@@ -1,10 +0,0 @@
1
- module Crags
2
- class Runner
3
- include Searcher
4
-
5
- def search_location(keyword, loc, category = 'sss')
6
- puts "Searching #{loc}..."
7
- super
8
- end
9
- end
10
- end
@@ -1,77 +0,0 @@
1
- module Crags
2
- module Searcher
3
- include Fetch
4
- include ERB::Util
5
-
6
- def strip_http(url)
7
- url.gsub(/^http\:\/\//,'').gsub(/\/$/,'')
8
- end
9
-
10
- def location_link(country)
11
- "http://geo.craigslist.org/iso/#{country}"
12
- end
13
-
14
- def location_doc(country)
15
- fetch_doc(location_link(country))
16
- end
17
-
18
- def location_request(country)
19
- fetch_request(location_link(country))
20
- end
21
-
22
- def location_links(country)
23
- location_doc(country).search("#list a")
24
- end
25
-
26
- def locations(country)
27
- linkz = location_links(country)
28
- if linkz.empty?
29
- [strip_http(location_request(country).last_effective_url)]
30
- else
31
- linkz.collect{|link| strip_http(link["href"]) }
32
- end
33
- end
34
-
35
- def categories
36
- doc = fetch_doc("http://sfbay.craigslist.org/")
37
- links = doc.search("table[@summary=\"for sale\"] a")
38
- categories = {}
39
- links.each do |link|
40
- categories[link.inner_html] = link["href"]
41
- end
42
- categories
43
- end
44
-
45
- def search(keyword, country = 'us', category = 'sss', &block)
46
- locations(country).collect do |loc|
47
- sleep(1 + rand(3))
48
- search_location(keyword, loc, category, &block)
49
- end.flatten
50
- end
51
-
52
- def items(doc)
53
- doc.search("item").collect do |item|
54
- hashify(item)
55
- end
56
- end
57
-
58
- def hashify(item)
59
- title = item.at("title").inner_text
60
- url = strip_http(item["rdf:about"])
61
- date = DateTime.parse(item.at("dc:date").inner_text)
62
- {:title => title, :url => url, :date => date}
63
- end
64
-
65
- def search_location_link(keyword, loc, category = 'sss')
66
- "http://#{loc}/search/#{category}?query=#{url_encode(keyword)}"
67
- end
68
-
69
- def search_location(keyword, loc, category = 'sss', &block)
70
- doc = fetch_doc("#{search_location_link(keyword, loc, category)}&format=rss")
71
- items(doc).collect do |item|
72
- yield item if block_given?
73
- item
74
- end
75
- end
76
- end
77
- end
@@ -1,33 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class Crags::FetchTest < Test::Unit::TestCase
4
- context "Fetch" do
5
- setup do
6
- extend Crags::Fetch
7
- end
8
-
9
- should "fetch doc should hpricot fetched html" do
10
- stubs(:fetch_html).with("url").returns("html")
11
- Hpricot.expects(:parse).with("html").returns("doc")
12
- fetch_doc("url").should == "doc"
13
- end
14
-
15
- should "fetch html should fetch_request a url" do
16
- curb = stub(:body_str => "uhh")
17
- expects(:fetch_request).with("url").returns(curb)
18
- fetch_html("url").should == "uhh"
19
- end
20
-
21
- should "create a new request" do
22
- req = stub(:follow_location= => nil, :perform => nil)
23
- Curl::Easy.expects(:new).with("url").returns(req)
24
- fetch_request("url").should == req
25
- end
26
-
27
- should "follow redirects for fetched requests" do
28
- req = mock(:follow_location= => nil, :perform => nil)
29
- Curl::Easy.stubs(:new).returns(req)
30
- fetch_request("url")
31
- end
32
- end
33
- end
@@ -1,25 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class Crags::ProxyTest < Test::Unit::TestCase
4
- context "Proxy" do
5
- setup do
6
- extend Crags::Proxy
7
- end
8
-
9
- should "lists should return a list of proxy list websites" do
10
- lists.should == ["http://www.proxy4free.com/page1.html", "http://www.proxy4free.com/page3.html"]
11
- end
12
-
13
- should "fetch lists should fetch html for each site in lists" do
14
- stubs(:lists).returns(["1", "2"])
15
- expects(:fetch_html).with("1").returns("html_1")
16
- expects(:fetch_html).with("2").returns("html_2")
17
- fetch_lists.should == ["html_1", "html_2"]
18
- end
19
-
20
- should "scan should return all ips in a text blizoc" do
21
- text = "192.168.1.2 omg dude!! wtf.f.f.asdasd9.8.9 78.900.42.32"
22
- scan(text).should == ["192.168.1.2", "78.900.42.32"]
23
- end
24
- end
25
- end
@@ -1,28 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class Crags::RunnerTest < Test::Unit::TestCase
4
- context "instance of Runner" do
5
- setup do
6
- @runner = Crags::Runner.new
7
- @runner.stubs(:fetch_doc)
8
- @runner.stubs(:items).returns([])
9
- end
10
-
11
- should "runner should include searcher" do
12
- Crags::Runner.ancestors.include?(Crags::Searcher).should == true
13
- end
14
-
15
- should "search location should puts message with loc" do
16
- @runner.expects(:puts).with { |val| val =~ /location/ }
17
- @runner.search_location("", "location", "category")
18
- end
19
-
20
- should "search location should take a category" do
21
- @runner.search_location("", "location", "category")
22
- end
23
-
24
- should "search location should have default category sss" do
25
- @runner.search_location("", "location")
26
- end
27
- end
28
- end