quixoten-craigler 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
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.
@@ -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.
@@ -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
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 1
3
+ :minor: 0
4
+ :patch: 0
@@ -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
@@ -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
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class CraiglerTest < Test::Unit::TestCase
4
+ should "respond to search" do
5
+ assert_respond_to(Craigler, :search)
6
+ end
7
+
8
+ should "respond to find" do
9
+ assert_respond_to(Craigler, :find)
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'craigler'
8
+
9
+ class Test::Unit::TestCase
10
+ end
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