Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit e87d45e1f9772cb410143be6f554908dea40256e 0 parents
@dwillis dwillis authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in times_wire.gemspec
+gemspec
9 Rakefile
@@ -0,0 +1,9 @@
+require 'bundler'
+require 'rake/testtask'
+include Rake::DSL
+Bundler::GemHelper.install_tasks
+Rake::TestTask.new(:test) do |test|
+ test.libs << 'lib' << 'test'
+ test.pattern = 'test/**/test_*.rb'
+ test.verbose = true
+end
3  lib/times_wire.rb
@@ -0,0 +1,3 @@
+%w(base item version).each do |f|
+ require File.join(File.dirname(__FILE__), 'times_wire', f)
+end
71 lib/times_wire/base.rb
@@ -0,0 +1,71 @@
+require 'rubygems'
+require 'open-uri'
+require 'json'
+require 'date'
+
+module TimesWire
+ class Base
+ API_SERVER = 'api.nytimes.com'
+ API_VERSION = 'v3'
+ API_NAME = 'news'
+ API_BASE = "/svc/#{API_NAME}/#{API_VERSION}/content"
+
+ @@api_key = nil
+ @@debug = false
+ @@copyright = nil
+
+ # The copyright footer to be placed at the bottom of any data from the New York Times. Note this is only set after an API call.
+ def copyright
+ @@copyright
+ end
+
+ ##
+ # Set the API key used for operations. This needs to be called before any requests against the API. To obtain an API key, go to http://developer.nytimes.com/
+ def self.api_key=(key)
+ @@api_key = key
+ end
+
+ def self.api_key
+ @@api_key
+ end
+
+ def self.date_parser(date)
+ date ? Date.parse(date) : nil
+ end
+
+ ##
+ # Builds a request URI to call the API server
+ def self.build_request_url(path, params)
+ URI::HTTP.build :host => API_SERVER, :path => "#{API_BASE}/#{path}.json", :query => params.map {|k,v| "#{k}=#{v}"}.join('&')
+ end
+
+ def self.invoke(path, params={})
+ begin
+ if @@api_key.nil?
+ raise "You must initialize the API key before you run any API queries"
+ end
+
+ full_params = params.merge 'api-key' => @@api_key
+
+ uri = build_request_url(path, full_params)
+
+ reply = uri.read
+ parsed_reply = JSON.parse reply
+
+ if parsed_reply.nil?
+ raise "Empty reply returned from API"
+ end
+
+ @@copyright = parsed_reply['copyright']
+
+ parsed_reply
+ rescue OpenURI::HTTPError => e
+ if e.message =~ /^404/
+ return nil
+ end
+
+ raise "Error connecting to URL #{uri} #{e}"
+ end
+ end
+ end
+end
43 lib/times_wire/item.rb
@@ -0,0 +1,43 @@
+module TimesWire
+ class Item < Base
+
+ attr_reader :section, :title, :abstract, :url, :byline, :item_type, :source, :updated_date, :created_date,
+ :published_date, :material_type_facet, :kicker, :subheadline, :multimedia, :des_facets, :org_facets,
+ :per_facets, :geo_facets, :related_urls
+
+ def initialize(params={})
+ params.each_pair do |k,v|
+ instance_variable_set("@#{k}", v)
+ end
+ end
+
+ def self.create_from_api(params={})
+ self.new :section => params['section'],
+ :title => params['title'],
+ :abstract => params['abstract'],
+ :url => params['url'],
+ :byline => params['byline'],
+ :item_type => params['item_type'],
+ :source => params['source'],
+ :updated_date => date_parser(params['updated_date']),
+ :created_date => date_parser(params['created_date']),
+ :published_date => date_parser(params['published_date']),
+ :material_type_facet => params['material_type_facet'],
+ :kicker => params['kicker'],
+ :subheadline => params['subheadline'],
+ :multimedia => params['multimedia'],
+ :des_facets => params['des_facet'],
+ :org_facets => params['org_facet'],
+ :per_facets => params['per_facet'],
+ :geo_facets => params['geo_facet'],
+ :related_urls => params['related_urls']
+ end
+
+ def self.latest(source="all", limit=20)
+ reply = Base.invoke("#{source}/all", {"limit" => limit})
+ results = reply['results']
+ @items = results.map {|r| Item.create_from_api(r)}
+ end
+
+ end
+end
3  lib/times_wire/version.rb
@@ -0,0 +1,3 @@
+module TimesWire
+ VERSION = "0.0.1"
+end
15 test/test_helper.rb
@@ -0,0 +1,15 @@
+require 'test/unit'
+require 'rubygems'
+require 'shoulda'
+require 'json'
+
+%w(base item).each do |f|
+ require File.join(File.dirname(__FILE__), '../lib/times_wire', f)
+end
+
+# set your NYT Times Newswire API key as an environment variable to run the tests
+API_KEY = ENV['NYT_TIMESWIRE_API_KEY']
+TimesWire::Base.api_key = API_KEY
+
+module TestTimesWire
+end
40 test/times_wire/test_item.rb
@@ -0,0 +1,40 @@
+class TestTimesWire::TestItem < Test::Unit::TestCase
+ include TimesWire
+
+ context "create single Item" do
+ setup do
+ reply = Base.invoke('', {"url" => "http://www.nytimes.com/2010/12/17/world/asia/17sanger.html"})
+ @result = reply['results'].first
+ @item = Item.create_from_api(@result)
+ end
+
+ should "return an object of the Item type" do
+ assert_kind_of(Item, @item)
+ end
+ end
+
+ context "create list of items from NYT only" do
+ setup do
+ @items = Item.latest('nyt')
+ end
+
+ should "return an array of 20 objects of the Item type from the NYT alone" do
+ assert_equal(20, @items.size)
+ assert_kind_of(Item, @items.first)
+ assert_equal(["The New York Times"], @items.map {|i| i.source}.uniq)
+ end
+ end
+
+ context "create list of 15 items from IHT only" do
+ setup do
+ @items = Item.latest('iht', 15)
+ end
+
+ should "return an array of 15 objects of the Item type from the IHT alone" do
+ assert_equal(15, @items.size)
+ assert_kind_of(Item, @items.first)
+ assert_equal(["International Herald Tribune"], @items.map {|i| i.source}.uniq)
+ end
+ end
+
+end
23 times_wire.gemspec
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "times_wire/version"
+
+Gem::Specification.new do |s|
+ s.name = "times_wire"
+ s.version = TimesWire::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Derek Willis"]
+ s.email = ["dwillis@gmail.com"]
+ s.homepage = "http://rubygems.org/gems/times_wire"
+ s.summary = %q{A thin client for The New York Times Newswire API}
+ s.description = %q{A Ruby library for parsing stories and blog posts from The New York Times Newswire API}
+
+ s.rubyforge_project = "times_wire"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ s.add_development_dependency "shoulda"
+end
Please sign in to comment.
Something went wrong with that request. Please try again.