quixoten-craigler 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +29 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/craigler.gemspec +50 -0
- data/lib/craigler.rb +24 -0
- data/lib/craigler/constants.rb +98 -0
- data/lib/craigler/search.rb +66 -0
- data/test/craigler_search_test.rb +58 -0
- data/test/craigler_test.rb +11 -0
- data/test/test_helper.rb +10 -0
- metadata +68 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Devin Christensen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
= craigler
|
2
|
+
|
3
|
+
Search API for craigslist
|
4
|
+
|
5
|
+
== SYNOPSIS:
|
6
|
+
|
7
|
+
Craigler.search(:motorcycles, :in => [:utah, :nevada, :arizona], :for => 'Boulevard M50) do |item|
|
8
|
+
puts item.title
|
9
|
+
puts item.url
|
10
|
+
puts item.time
|
11
|
+
end
|
12
|
+
|
13
|
+
Craigler.find('Boulevard M50', :in => [:utah, :nevada, :arizona], :only => :motorcycles) do |item|
|
14
|
+
puts item.title
|
15
|
+
puts item.url
|
16
|
+
puts item.time
|
17
|
+
end
|
18
|
+
|
19
|
+
== REQUIREMENTS:
|
20
|
+
|
21
|
+
* Hpricot
|
22
|
+
|
23
|
+
== INSTALL:
|
24
|
+
|
25
|
+
* sudo gem install quixoten-craigler
|
26
|
+
|
27
|
+
== Copyright
|
28
|
+
|
29
|
+
Copyright (c) 2009 Devin Christensen. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "craigler"
|
8
|
+
gem.summary = %Q{Search API for craigslist}
|
9
|
+
gem.email = "quixoten@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/quixoten/craigler"
|
11
|
+
gem.authors = ["Devin Christensen"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
Rake::TestTask.new(:test) do |test|
|
21
|
+
test.libs << 'lib' << 'test'
|
22
|
+
test.pattern = 'test/**/*_test.rb'
|
23
|
+
test.verbose = true
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'rcov/rcovtask'
|
28
|
+
Rcov::RcovTask.new do |test|
|
29
|
+
test.libs << 'test'
|
30
|
+
test.pattern = 'test/**/*_test.rb'
|
31
|
+
test.verbose = true
|
32
|
+
end
|
33
|
+
rescue LoadError
|
34
|
+
task :rcov do
|
35
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
if File.exist?('VERSION.yml')
|
45
|
+
config = YAML.load(File.read('VERSION.yml'))
|
46
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
47
|
+
else
|
48
|
+
version = ""
|
49
|
+
end
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "craigler #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
56
|
+
|
data/VERSION.yml
ADDED
data/craigler.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{craigler}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Devin Christensen"]
|
9
|
+
s.date = %q{2009-07-06}
|
10
|
+
s.email = %q{quixoten@gmail.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION.yml",
|
22
|
+
"craigler.gemspec",
|
23
|
+
"lib/craigler.rb",
|
24
|
+
"lib/craigler/constants.rb",
|
25
|
+
"lib/craigler/search.rb",
|
26
|
+
"test/craigler_search_test.rb",
|
27
|
+
"test/craigler_test.rb",
|
28
|
+
"test/test_helper.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/quixoten/craigler}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.3.4}
|
34
|
+
s.summary = %q{Search API for craigslist}
|
35
|
+
s.test_files = [
|
36
|
+
"test/craigler_search_test.rb",
|
37
|
+
"test/craigler_test.rb",
|
38
|
+
"test/test_helper.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
|
+
else
|
47
|
+
end
|
48
|
+
else
|
49
|
+
end
|
50
|
+
end
|
data/lib/craigler.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'Hpricot'
|
3
|
+
|
4
|
+
require 'craigler/constants'
|
5
|
+
require 'craigler/search'
|
6
|
+
|
7
|
+
module Craigler
|
8
|
+
VERSION = '0.1.0'
|
9
|
+
|
10
|
+
class CraiglerError < StandardError; end
|
11
|
+
class InvalidCategory < CraiglerError; end
|
12
|
+
class InvalidSearchTerm < CraiglerError; end
|
13
|
+
class InvalidLocation < CraiglerError; end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def search(category, options = {})
|
17
|
+
search = Search.new(options[:for], :in => (options[:in] || :anywhere), :only => category)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find(search_term, options = {})
|
21
|
+
search = Search.new(search_term, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Craigler
|
2
|
+
LOCATIONS = {
|
3
|
+
:alabama => ['http://auburn.craigslist.org/','http://bham.craigslist.org/','http://columbusga.craigslist.org/','http://dothan.craigslist.org/','http://shoals.craigslist.org/','http://gadsden.craigslist.org/','http://huntsville.craigslist.org/','http://mobile.craigslist.org/','http://montgomery.craigslist.org/','http://tuscaloosa.craigslist.org/'],
|
4
|
+
:alaska => ['http://anchorage.craigslist.org/'],
|
5
|
+
:arizona => ['http://flagstaff.craigslist.org/','http://mohave.craigslist.org/','http://phoenix.craigslist.org/','http://prescott.craigslist.org/','http://sierravista.craigslist.org/','http://tucson.craigslist.org/','http://yuma.craigslist.org/'],
|
6
|
+
:arkansas => ['http://fayar.craigslist.org/','http://fortsmith.craigslist.org/','http://jonesboro.craigslist.org/','http://littlerock.craigslist.org/','http://memphis.craigslist.org/','http://texarkana.craigslist.org/'],
|
7
|
+
:california => ['http://sfbay.craigslist.org/','http://bakersfield.craigslist.org/','http://chico.craigslist.org/','http://fresno.craigslist.org/','http://goldcountry.craigslist.org/','http://humboldt.craigslist.org/','http://imperial.craigslist.org/','http://inlandempire.craigslist.org/','http://losangeles.craigslist.org/','http://mendocino.craigslist.org/','http://merced.craigslist.org/','http://modesto.craigslist.org/','http://monterey.craigslist.org/','http://orangecounty.craigslist.org/','http://palmsprings.craigslist.org/','http://redding.craigslist.org/','http://reno.craigslist.org/','http://sacramento.craigslist.org/','http://sandiego.craigslist.org/','http://slo.craigslist.org/','http://santabarbara.craigslist.org/','http://stockton.craigslist.org/','http://ventura.craigslist.org/','http://visalia.craigslist.org/','http://yubasutter.craigslist.org/'],
|
8
|
+
:colorado => ['http://boulder.craigslist.org/','http://cosprings.craigslist.org/','http://denver.craigslist.org/','http://fortcollins.craigslist.org/','http://pueblo.craigslist.org/','http://rockies.craigslist.org/','http://westslope.craigslist.org/'],
|
9
|
+
:connecticut => ['http://newlondon.craigslist.org/','http://hartford.craigslist.org/','http://newhaven.craigslist.org/','http://nwct.craigslist.org/'],
|
10
|
+
:delaware => ['http://delaware.craigslist.org/'],
|
11
|
+
:dc => ['http://washingtondc.craigslist.org/'],
|
12
|
+
:florida => ['http://daytona.craigslist.org/','http://keys.craigslist.org/','http://fortmyers.craigslist.org/','http://gainesville.craigslist.org/','http://jacksonville.craigslist.org/','http://lakeland.craigslist.org/','http://ocala.craigslist.org/','http://orlando.craigslist.org/','http://panamacity.craigslist.org/','http://pensacola.craigslist.org/','http://sarasota.craigslist.org/','http://miami.craigslist.org/','http://spacecoast.craigslist.org/','http://staugustine.craigslist.org/','http://tallahassee.craigslist.org/','http://tampa.craigslist.org/','http://treasure.craigslist.org/'],
|
13
|
+
:georgia => ['http://athensga.craigslist.org/','http://atlanta.craigslist.org/','http://augusta.craigslist.org/','http://brunswick.craigslist.org/','http://columbusga.craigslist.org/','http://macon.craigslist.org/','http://savannah.craigslist.org/','http://valdosta.craigslist.org/'],
|
14
|
+
:hawaii => ['http://honolulu.craigslist.org/'],
|
15
|
+
:idaho => ['http://boise.craigslist.org/','http://eastidaho.craigslist.org/','http://pullman.craigslist.org/','http://spokane.craigslist.org/','http://twinfalls.craigslist.org/'],
|
16
|
+
:illinois => ['http://bn.craigslist.org/','http://carbondale.craigslist.org/','http://chambana.craigslist.org/','http://chicago.craigslist.org/','http://decatur.craigslist.org/','http://peoria.craigslist.org/','http://quadcities.craigslist.org/','http://rockford.craigslist.org/','http://springfieldil.craigslist.org/','http://stlouis.craigslist.org/'],
|
17
|
+
:indiana => ['http://bloomington.craigslist.org/','http://evansville.craigslist.org/','http://fortwayne.craigslist.org/','http://indianapolis.craigslist.org/','http://tippecanoe.craigslist.org/','http://muncie.craigslist.org/','http://southbend.craigslist.org/','http://terrahaute.craigslist.org/'],
|
18
|
+
:iowa => ['http://ames.craigslist.org/','http://cedarrapids.craigslist.org/','http://desmoines.craigslist.org/','http://dubuque.craigslist.org/','http://iowacity.craigslist.org/','http://omaha.craigslist.org/','http://quadcities.craigslist.org/','http://siouxcity.craigslist.org/','http://waterloo.craigslist.org/'],
|
19
|
+
:kansas => ['http://kansascity.craigslist.org/','http://lawrence.craigslist.org/','http://ksu.craigslist.org/','http://topeka.craigslist.org/','http://wichita.craigslist.org/'],
|
20
|
+
:kentucky => ['http://bgky.craigslist.org/','http://cincinnati.craigslist.org/','http://huntington.craigslist.org/','http://lexington.craigslist.org/','http://louisville.craigslist.org/','http://westky.craigslist.org/'],
|
21
|
+
:louisiana => ['http://batonrouge.craigslist.org/','http://lafayette.craigslist.org/','http://lakecharles.craigslist.org/','http://monroe.craigslist.org/','http://neworleans.craigslist.org/','http://shreveport.craigslist.org/'],
|
22
|
+
:maine => ['http://maine.craigslist.org/'],
|
23
|
+
:maryland => ['http://annapolis.craigslist.org/','http://baltimore.craigslist.org/','http://easternshore.craigslist.org/','http://smd.craigslist.org/','http://westmd.craigslist.org/'],
|
24
|
+
:mass => ['http://boston.craigslist.org/','http://capecod.craigslist.org/','http://southcoast.craigslist.org/','http://westernmass.craigslist.org/','http://worcester.craigslist.org/'],
|
25
|
+
:michigan => ['http://annarbor.craigslist.org/','http://centralmich.craigslist.org/','http://detroit.craigslist.org/','http://flint.craigslist.org/','http://grandrapids.craigslist.org/','http://jxn.craigslist.org/','http://kalamazoo.craigslist.org/','http://lansing.craigslist.org/','http://muskegon.craigslist.org/','http://nmi.craigslist.org/','http://porthuron.craigslist.org/','http://saginaw.craigslist.org/','http://southbend.craigslist.org/','http://swmi.craigslist.org/','http://up.craigslist.org/'],
|
26
|
+
:minnesota => ['http://duluth.craigslist.org/','http://fargo.craigslist.org/','http://mankato.craigslist.org/','http://minneapolis.craigslist.org/','http://rmn.craigslist.org/','http://stcloud.craigslist.org/'],
|
27
|
+
:mississippi => ['http://gulfport.craigslist.org/','http://hattiesburg.craigslist.org/','http://jackson.craigslist.org/','http://memphis.craigslist.org/','http://northmiss.craigslist.org/'],
|
28
|
+
:missouri => ['http://columbiamo.craigslist.org/','http://joplin.craigslist.org/','http://kansascity.craigslist.org/','http://semo.craigslist.org/','http://springfield.craigslist.org/','http://stlouis.craigslist.org/'],
|
29
|
+
:montana => ['http://montana.craigslist.org/'],
|
30
|
+
:nebraska => ['http://grandisland.craigslist.org/','http://lincoln.craigslist.org/','http://omaha.craigslist.org/','http://siouxcity.craigslist.org/'],
|
31
|
+
:nevada => ['http://lasvegas.craigslist.org/','http://reno.craigslist.org/'],
|
32
|
+
:n_hampshire => ['http://nh.craigslist.org/'],
|
33
|
+
:new_jersey => ['http://cnj.craigslist.org/','http://jerseyshore.craigslist.org/','http://newjersey.craigslist.org/','http://southjersey.craigslist.org/'],
|
34
|
+
:new_mexico => ['http://albuquerque.craigslist.org/','http://farmington.craigslist.org/','http://lascruces.craigslist.org/','http://roswell.craigslist.org/','http://santafe.craigslist.org/'],
|
35
|
+
:new_york => ['http://albany.craigslist.org/','http://binghamton.craigslist.org/','http://buffalo.craigslist.org/','http://catskills.craigslist.org/','http://chautauqua.craigslist.org/','http://elmira.craigslist.org/','http://hudsonvalley.craigslist.org/','http://ithaca.craigslist.org/','http://longisland.craigslist.org/','http://newyork.craigslist.org/','http://plattsburgh.craigslist.org/','http://rochester.craigslist.org/','http://syracuse.craigslist.org/','http://utica.craigslist.org/','http://watertown.craigslist.org/'],
|
36
|
+
:n_carolina => ['http://asheville.craigslist.org/','http://boone.craigslist.org/','http://charlotte.craigslist.org/','http://eastnc.craigslist.org/','http://fayetteville.craigslist.org/','http://greensboro.craigslist.org/','http://hickory.craigslist.org/','http://outerbanks.craigslist.org/','http://raleigh.craigslist.org/','http://wilmington.craigslist.org/','http://winstonsalem.craigslist.org/'],
|
37
|
+
:north_dakota => ['http://fargo.craigslist.org/','http://nd.craigslist.org/'],
|
38
|
+
:ohio => ['http://akroncanton.craigslist.org/','http://athensohio.craigslist.org/','http://cincinnati.craigslist.org/','http://cleveland.craigslist.org/','http://columbus.craigslist.org/','http://dayton.craigslist.org/','http://huntington.craigslist.org/','http://limaohio.craigslist.org/','http://mansfield.craigslist.org/','http://parkersburg.craigslist.org/','http://sandusky.craigslist.org/','http://toledo.craigslist.org/','http://wheeling.craigslist.org/','http://youngstown.craigslist.org/'],
|
39
|
+
:oklahoma => ['http://fortsmith.craigslist.org/','http://lawton.craigslist.org/','http://oklahomacity.craigslist.org/','http://stillwater.craigslist.org/','http://tulsa.craigslist.org/'],
|
40
|
+
:oregon => ['http://bend.craigslist.org/','http://corvallis.craigslist.org/','http://eastoregon.craigslist.org/','http://eugene.craigslist.org/','http://medford.craigslist.org/','http://oregoncoast.craigslist.org/','http://portland.craigslist.org/','http://roseburg.craigslist.org/','http://salem.craigslist.org/'],
|
41
|
+
:pennsylvania => ['http://altoona.craigslist.org/','http://erie.craigslist.org/','http://harrisburg.craigslist.org/','http://lancaster.craigslist.org/','http://allentown.craigslist.org/','http://philadelphia.craigslist.org/','http://pittsburgh.craigslist.org/','http://poconos.craigslist.org/','http://reading.craigslist.org/','http://scranton.craigslist.org/','http://pennstate.craigslist.org/','http://williamsport.craigslist.org/','http://york.craigslist.org/'],
|
42
|
+
:rhode_island => ['http://providence.craigslist.org/'],
|
43
|
+
:s_carolina => ['http://charleston.craigslist.org/','http://columbia.craigslist.org/','http://florencesc.craigslist.org/','http://greenville.craigslist.org/','http://hiltonhead.craigslist.org/','http://myrtlebeach.craigslist.org/'],
|
44
|
+
:south_dakota => ['http://sd.craigslist.org/'],
|
45
|
+
:tennessee => ['http://chattanooga.craigslist.org/','http://clarksville.craigslist.org/','http://jacksontn.craigslist.org/','http://knoxville.craigslist.org/','http://memphis.craigslist.org/','http://nashville.craigslist.org/','http://tricities.craigslist.org/'],
|
46
|
+
:texas => ['http://abilene.craigslist.org/','http://amarillo.craigslist.org/','http://austin.craigslist.org/','http://beaumont.craigslist.org/','http://brownsville.craigslist.org/','http://collegestation.craigslist.org/','http://corpuschristi.craigslist.org/','http://dallas.craigslist.org/','http://elpaso.craigslist.org/','http://galveston.craigslist.org/','http://houston.craigslist.org/','http://killeen.craigslist.org/','http://laredo.craigslist.org/','http://lubbock.craigslist.org/','http://mcallen.craigslist.org/','http://odessa.craigslist.org/','http://sanantonio.craigslist.org/','http://sanmarcos.craigslist.org/','http://texarkana.craigslist.org/','http://easttexas.craigslist.org/','http://victoriatx.craigslist.org/','http://waco.craigslist.org/','http://wichitafalls.craigslist.org/'],
|
47
|
+
:utah => ['http://logan.craigslist.org/','http://ogden.craigslist.org/','http://provo.craigslist.org/','http://saltlakecity.craigslist.org/','http://stgeorge.craigslist.org/'],
|
48
|
+
:vermont => ['http://burlington.craigslist.org/'],
|
49
|
+
:virginia => ['http://blacksburg.craigslist.org/','http://charlottesville.craigslist.org/','http://danville.craigslist.org/','http://easternshore.craigslist.org/','http://fredericksburg.craigslist.org/','http://norfolk.craigslist.org/','http://harrisonburg.craigslist.org/','http://lynchburg.craigslist.org/','http://richmond.craigslist.org/','http://roanoke.craigslist.org/'],
|
50
|
+
:washington => ['http://bellingham.craigslist.org/','http://kpr.craigslist.org/','http://olympic.craigslist.org/','http://pullman.craigslist.org/','http://seattle.craigslist.org/','http://skagit.craigslist.org/','http://spokane.craigslist.org/','http://wenatchee.craigslist.org/','http://yakima.craigslist.org/'],
|
51
|
+
:west_virginia => ['http://charlestonwv.craigslist.org/','http://huntington.craigslist.org/','http://martinsburg.craigslist.org/','http://morgantown.craigslist.org/','http://parkersburg.craigslist.org/','http://wv.craigslist.org/','http://wheeling.craigslist.org/'],
|
52
|
+
:wisconsin => ['http://appleton.craigslist.org/','http://duluth.craigslist.org/','http://eauclaire.craigslist.org/','http://greenbay.craigslist.org/','http://janesville.craigslist.org/','http://racine.craigslist.org/','http://lacrosse.craigslist.org/','http://madison.craigslist.org/','http://milwaukee.craigslist.org/','http://sheboygan.craigslist.org/','http://wausau.craigslist.org/'],
|
53
|
+
:wyoming => ['http://wyoming.craigslist.org/']
|
54
|
+
}
|
55
|
+
|
56
|
+
CATEGORIES = {
|
57
|
+
:community => 'ccc',
|
58
|
+
:event => 'eee',
|
59
|
+
:all_for_sale_or_wanted => 'sss',
|
60
|
+
:art_and_crafts => 'art',
|
61
|
+
:auto_parts => 'pts',
|
62
|
+
:baby_and_kid_stuff => 'bab',
|
63
|
+
:barter => 'bar',
|
64
|
+
:bicycles => 'bik',
|
65
|
+
:boats => 'boa',
|
66
|
+
:books => 'bks',
|
67
|
+
:business => 'bfs',
|
68
|
+
:cars_and_trucks => 'cta',
|
69
|
+
:media => 'emd',
|
70
|
+
:clothing => 'clo',
|
71
|
+
:collectibles => 'clt',
|
72
|
+
:computers_and_tech => 'sys',
|
73
|
+
:electronics => 'ele',
|
74
|
+
:farm_and_garden => 'grd',
|
75
|
+
:free_stuff => 'zip',
|
76
|
+
:furniture => 'fua',
|
77
|
+
:games_and_toys => 'tag',
|
78
|
+
:garage_sales => 'gms',
|
79
|
+
:general => 'for',
|
80
|
+
:household => 'hsh',
|
81
|
+
:items_wanted => 'wan',
|
82
|
+
:jewelry => 'jwl',
|
83
|
+
:materials => 'mat',
|
84
|
+
:motorcycles => 'mcy',
|
85
|
+
:musical_instruments => 'msg',
|
86
|
+
:photo_and_video => 'pho',
|
87
|
+
:recreational_vehicles => 'rvs',
|
88
|
+
:sporting_goods => 'spo',
|
89
|
+
:tickets => 'tix',
|
90
|
+
:tools => 'tls',
|
91
|
+
:gigs => 'ggg',
|
92
|
+
:housing => 'hhh',
|
93
|
+
:jobs => 'jjj',
|
94
|
+
:personals => 'ppp',
|
95
|
+
:resume => 'res',
|
96
|
+
:services_offered => 'bbb'
|
97
|
+
}
|
98
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Craigler
|
4
|
+
class Search
|
5
|
+
include ERB::Util
|
6
|
+
|
7
|
+
attr_reader :search_term, :categories, :locations
|
8
|
+
|
9
|
+
def initialize(search_term, options = {})
|
10
|
+
raise InvalidSearchTerm if search_term.nil? || search_term == ''
|
11
|
+
|
12
|
+
@search_term = search_term
|
13
|
+
@results = nil
|
14
|
+
_parse_options(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def results(refresh = false)
|
18
|
+
return @results unless @results.nil? || refresh
|
19
|
+
|
20
|
+
@results = []
|
21
|
+
_for_each_locations_search_url() do |location, url|
|
22
|
+
(0..19).each do |page|
|
23
|
+
items = _extract_items_from_url(location, "#{url}&s=#{page*25}")
|
24
|
+
@results.push(*items)
|
25
|
+
break unless items.size == 25
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
results
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def _parse_options(options)
|
34
|
+
options = {:in => LOCATIONS.keys, :only => :all_for_sale_or_wanted}.merge(options)
|
35
|
+
@locations = options[:in].is_a?(Array) ? options[:in] : [options[:in]]
|
36
|
+
@categories = options[:only].is_a?(Array) ? options[:only] : [options[:only]]
|
37
|
+
|
38
|
+
@locations.each() do |location|
|
39
|
+
raise InvalidLocation unless location == :anywhere || LOCATIONS.key?(location)
|
40
|
+
end
|
41
|
+
|
42
|
+
@categories.each() do |category|
|
43
|
+
raise InvalidCategory unless category == :all_for_sale_or_wanted || CATEGORIES.key?(category)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def _for_each_locations_search_url()
|
48
|
+
@locations.each do |location|
|
49
|
+
LOCATIONS[location].each do |url|
|
50
|
+
@categories.each do |category|
|
51
|
+
yield(location, "#{url}search/#{CATEGORIES[category]}?query=#{url_encode(@search_term)}&format=rss")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def _extract_items_from_url(location, url)
|
58
|
+
(Hpricot(open(url))/'item').collect { |item| {
|
59
|
+
:url => item['rdf:about'],
|
60
|
+
:title => (item%'title').inner_text,
|
61
|
+
:location => location.to_s,
|
62
|
+
:published_at => Time.parse((item%'dc:date').inner_text)
|
63
|
+
}}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CraiglerSearchTest < Test::Unit::TestCase
|
4
|
+
context "creating a search" do
|
5
|
+
should "require a valid category" do
|
6
|
+
assert_raises(Craigler::InvalidCategory) do
|
7
|
+
Craigler::Search.new('Yamaha Radian', :only => :invalid)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
should "require a search term" do
|
12
|
+
assert_raises(Craigler::InvalidSearchTerm) do
|
13
|
+
Craigler::Search.new(nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_raises(ArgumentError) do
|
17
|
+
Craigler::Search.new()
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should "not require a location" do
|
22
|
+
assert_nothing_raised() do
|
23
|
+
Craigler::Search.new('Yamaha Roadstar Warrior', :only => :motorcycles)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not require a category" do
|
28
|
+
assert_nothing_raised() do
|
29
|
+
Craigler::Search.new('Honda Shadow', :in => :utah)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
should "require that the location is valid" do
|
34
|
+
assert_raises(Craigler::InvalidLocation) do
|
35
|
+
Craigler::Search.new('Honda Nighthawk', :in => :invalid)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
should "accept multiple locations" do
|
40
|
+
assert_nothing_raised() do
|
41
|
+
Craigler::Search.new('Suzuki Boulevard M50', :in => [:utah, :nevada])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "fetching search results" do
|
47
|
+
setup do
|
48
|
+
@search = Craigler::Search.new('Honda Shadow', :in => :utah, :only => :motorcycles)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "return an array of hashes" do
|
52
|
+
results = @search.results()
|
53
|
+
assert(results.is_a?(Array), "Array exptected but was #{results.class}")
|
54
|
+
assert(results.size > 0, "No results were returned")
|
55
|
+
assert(results.inject(true) {|t,r| t && r.is_a?(Hash)})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: quixoten-craigler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Devin Christensen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-06 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: quixoten@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- VERSION.yml
|
32
|
+
- craigler.gemspec
|
33
|
+
- lib/craigler.rb
|
34
|
+
- lib/craigler/constants.rb
|
35
|
+
- lib/craigler/search.rb
|
36
|
+
- test/craigler_search_test.rb
|
37
|
+
- test/craigler_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
has_rdoc: false
|
40
|
+
homepage: http://github.com/quixoten/craigler
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.2.0
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Search API for craigslist
|
65
|
+
test_files:
|
66
|
+
- test/craigler_search_test.rb
|
67
|
+
- test/craigler_test.rb
|
68
|
+
- test/test_helper.rb
|