quixoten-craigler 1.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.
- 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
         |