lib/nytimes_articles/article.rb in harrisj-nytimes-articles-0.1.1 vs lib/nytimes_articles/article.rb in harrisj-nytimes-articles-0.1.2
- old
+ new
@@ -1,21 +1,28 @@
require 'rubygems'
module Nytimes
module Articles
+ ##
+ # The Article class represents a single article returned from the New York Times Article Search API. Note that an article can have many attributes
+ # but these are not necessarily populated unless you explicitly request them in the reply from the server via the <tt>:fields</tt> parameter to
+ # search (or use <tt>:fields => :all</tt>).
class Article < Base
RAW_FIELDS = %w(url)
TEXT_FIELDS = %w(abstract author body byline lead_paragraph nytd_lead_paragraph nytd_title title)
NUMERIC_FIELDS = %w(word_count)
BOOLEAN_FIELDS = %w(fee small_image)
IMAGE_FIELDS = %w(small_image small_image_url small_image_height small_image_width)
MULTIMEDIA_FIELDS = %w(multimedia related_multimedia)
- ALL_FIELDS = TEXT_FIELDS + RAW_FIELDS + NUMERIC_FIELDS + BOOLEAN_FIELDS + IMAGE_FIELDS + MULTIMEDIA_FIELDS + Facet::ALL_FACETS
+ ALL_FIELDS = TEXT_FIELDS + RAW_FIELDS + NUMERIC_FIELDS + BOOLEAN_FIELDS + MULTIMEDIA_FIELDS + Facet::ALL_FACETS + IMAGE_FIELDS
attr_reader *ALL_FIELDS
+ # special additional objects
+ attr_reader :thumbnail
+
# Scalar facets
attr_reader :page, :column, :pub_month, :pub_year, :pub_day, :day_of_week, :desk, :date, :section_page, :source
# Facets that return multiple values
attr_reader :classifiers, :descriptions, :geo, :material_types, :organizations, :persons, :nytd_bylines, :nytd_descriptions, :nytd_geo, :nytd_organizations, :nytd_persons, :nytd_sections, :nytd_works_mentioned, :works_mentioned
@@ -51,11 +58,11 @@
:fee => params['fee'] || false,
:lead_paragraph => text_field(params['lead_paragraph']),
:nytd_title => text_field(params['nytd_title']),
:nytd_lead_paragraph => text_field(params['nytd_lead_paragraph']),
:related_multimedia => nil, # FIXME
- :image => nil, # FIXME
+ :thumbnail => Thumbnail.init_from_api(params),
:title => text_field(params['title']),
:url => params['url'],
:word_count => integer_field(params['word_count']),
# FACETS THAT RETURN SCALARS
@@ -149,20 +156,22 @@
# * <tt>Facet::NYTD_ORGANIZATION</tt> - Standardized names of organizations, assigned for use on NYTimes.com (to get standardized terms, use the TimesTags API). When used in a request, values must be Mixed Case
# * <tt>Facet::NYTD_PERSON</tt> - Standardized names of people, assigned for use on NYTimes.com (to get standardized terms, use the TimesTags API). When used in a request, values must be Mixed Case.
# * <tt>Facet::NYTD_SECTION</tt> - The section the article appears in (on NYTimes.com)
# * <tt>Facet::NYTD_WORKS_MENTIONED</tt> - Literary works mentioned (titles formatted for use on NYTimes.com)
#
+ # Note that for your convenience you can also search with symbol versions of the constants (<tt>:geo => ['MANHATTAN']</tt>). Even pluralization is supported. To get the string API version of the facet use Facet#symbol_name
+ #
# The following two search fields are used for facet searching:
- # * <tt>:search_facets</tt> - takes a single value or array of facets to search. Facets can either be specified as array pairs (like <tt>[Facet::GEOGRAPHIC, 'CALIFORNIA']</tt>) or facets returned from a previous search can be passed directly. A single string can be passed as well if you have hand-crafted string.
- # * <tt>:exclude_facets</tt> - similar to <tt>:search_facets</tt> but is used to specify a list of facets to exclude.
+ # * <tt>:only_facets</tt> - takes a single value or array of facets to search. Facets can either be specified as array pairs (like <tt>[Facet::GEOGRAPHIC, 'CALIFORNIA']</tt>) or facets returned from a previous search can be passed directly. A single string can be passed as well if you have hand-crafted string.
+ # * <tt>:except_facets</tt> - similar to <tt>:only_facets</tt> but is used to specify a list of facets to exclude.
#
# == OTHER SEARCH FIELDS
- # * <tt>:fee</tt> - to be implemented
+ # * <tt>:fee</tt> - if set to true, only returns articles that must be purchased. If false, returns only free articles. If not specified, returns all articles
# * <tt>:begin_date</tt>, <tt>:end_date</tt> - the parameters are used to specify a start and end date for search results. BOTH of these must be provided or the API will return an error. Accepts either a Time/Date argument or a string of the format YYYYMMDD. For convenience the following alternative methods are provided
# * <tt>:before</tt> - an alternative to :end_date. Automatically adds a :before_date of sometime in 1980 if no :since argument is also provided; to be implemented
# * <tt>:since</tt> - An alternative to :begin_date. Automatically adds an :end_date of Time.now if no :before argument is provided; to be implemented.
- # * <tt>:has_thumbnail</tt> - to be implemented
+ # * <tt>:has_thumbnail</tt> - returns only articles that have thumbnail images associated. Note that to see the thumbnails, you must specify either <tt>:thumbnail</tt> or <tt>:all</tt> in the <tt>:fields</tt> argument).
# * <tt>:has_multimedia</tt> - to be implemented
#
# == FACET SUMMARIES
#
# The <tt>:facets</tt> argument can be used to specify up to 5 facet fields to be returned alongside the search that provide overall counts
@@ -191,14 +200,14 @@
end
api_params = {}
add_query_params(api_params, params)
- add_search_facets_param(api_params, params)
+ add_facet_conditions_params(api_params, params)
add_boolean_params(api_params, params)
- add_fields_param(api_params, params)
add_facets_param(api_params, params)
+ add_fields_param(api_params, params)
add_rank_params(api_params, params)
add_date_params(api_params, params)
add_offset_params(api_params, params)
reply = invoke(api_params)
@@ -237,24 +246,38 @@
ResultSet.init_from_api(reply)
end
def self.add_facets_param(out_params, in_params)
if in_params[:facets]
- out_params['facets'] = in_params[:facets].to_a.join(',')
+ out_params['facets'] = in_params[:facets].to_a.map {|f| Facet.symbol_name(f)}.join(',')
end
end
+ def self.field_param(name)
+ case name.to_s
+ when 'thumbnail'
+ IMAGE_FIELDS.join(',')
+ else
+ name.to_s
+ end
+ end
+
def self.add_fields_param(out_params, in_params)
case in_params[:fields]
when nil
# do nothing
when :all
out_params['fields'] = ALL_FIELDS.join(',')
+ when :none
+ out_params['fields'] = ' '
+ unless out_params['facets']
+ out_params['facets'] = Facet::DEFAULT_RETURN_FACETS.join(',')
+ end
when String, Symbol
- out_params['fields'] = in_params[:fields].to_s
+ out_params['fields'] = field_param(in_params[:fields])
when Array
- out_params['fields'] = in_params[:fields].map {|f| f.to_s}.join(',')
+ out_params['fields'] = in_params[:fields].map {|f| field_param(f)}.join(',')
else
raise ArgumentError, "Fields must either be :all, a single field name, or an array of field names (either strings or symbols)"
end
end
@@ -277,23 +300,27 @@
def self.facet_argument(name, value, exclude = false)
unless value.is_a? Array
value = [value]
end
+ if name.is_a? Symbol
+ name = Facet.symbol_name(name)
+ end
+
"#{'-' if exclude}#{name}:[#{value.join(',')}]"
end
def self.parse_facet_params(facets, exclude = false)
- search_facets = []
+ facet_args = []
case facets
when nil
# do nothing
when String
- search_facets = [facets]
+ facet_args = [facets]
when Facet
- search_facets = [facet_argument(facets.facet_type, facets.term, exclude)]
+ facet_args = [facet_argument(facets.facet_type, facets.term, exclude)]
when Array
unless facets.all? {|f| f.is_a? Facet }
raise ArgumentError, "Only Facet instances can be passed in as an array; use Hash for Facet::Name => values input"
end
@@ -305,25 +332,25 @@
facet_hash[f.facet_type] << f.term
end
facet_hash.each_pair do |k,v|
- search_facets << facet_argument(k, v, exclude)
+ facet_args << facet_argument(k, v, exclude)
end
when Hash
facets.each_pair do |k,v|
- search_facets << facet_argument(k, v, exclude)
+ facet_args << facet_argument(k, v, exclude)
end
end
- search_facets
+ facet_args
end
- def self.add_search_facets_param(out_params, in_params)
+ def self.add_facet_conditions_params(out_params, in_params)
query = out_params['query']
- search_facets = parse_facet_params(in_params[:search_facets])
- exclude_facets = parse_facet_params(in_params[:exclude_facets], true)
+ search_facets = parse_facet_params(in_params[:only_facets])
+ exclude_facets = parse_facet_params(in_params[:except_facets], true)
unless search_facets.empty? && exclude_facets.empty?
out_params['query'] = ([query] + search_facets + exclude_facets).compact.join(' ')
end
end
\ No newline at end of file