module News
Public Class Methods
autogen_feed_key( feed_url )
click to toggle source
helpers
# File lib/newscast.rb, line 68 def self.autogen_feed_key( feed_url ) ## note: ## use a "fingerprint" hash digest as key ## do NOT include scheme (e.g. https or http) ## do NOT include port ## so you can change it without "breaking" the key - why? why not? ## ## e.g. u = URI( 'https://example.com:333/a/b?f=xml' ## u.host+u.request_uri ## #=> example.com/a/b?f=xml uri = URI( feed_url ) ## note: add host in "plain" text - making errors and the key more readable ## note: cut-off www. if leading e.g. www.ruby-lang.org => ruby-lang.org host = uri.host.downcase.sub( /^www\./, '' ) # use a differt separator e.g _ or ~ and NOT $ - why? why not? key = "#{host}$#{Digest::MD5.hexdigest( uri.request_uri )}" key end
between( start_date, end_date )
click to toggle source
# File lib/newscast.rb, line 220 def self.between( start_date, end_date ) ## helper for week, q1, q2, etc. q_start = start_date.strftime('%Y-%m-%d') q_end = end_date.strftime('%Y-%m-%d') items. where( Arel.sql( "date(coalesce(items.updated,items.published,'1970-01-01')) BETWEEN '#{q_start}' AND '#{q_end}'" ) ) end
channels()
click to toggle source
# File lib/newscast.rb, line 189 def self.channels() feeds; end
config()
click to toggle source
# File lib/newscast.rb, line 329 def self.config @config ||= Configuration.new end
configure() { |config| ... }
click to toggle source
# File lib/newscast.rb, line 325 def self.configure yield( config ) end
connection()
click to toggle source
# File lib/newscast.rb, line 347 def self.connection ## use for "auto-magic" connection w/ automigrate ## todo/fix: check - "just simply" return ActiveRecord connection - possible - why? why not? ## do NOT use our own Connection class @connection ||= Connection.new end
feeds()
click to toggle source
# File lib/newscast.rb, line 176 def self.feeds connection ## note: always use "multi-site" setup; defaults to 'news' site key ## note: add "default" scope - orders (sorts) by latest / time rec = Pluto::Model::Site.where(key: site).first if rec.nil? Pluto::Model::Feed.none ## use null (relation) pattern to avoid crash on nil - why? why not? else rec.feeds.order( Arel.sql( "coalesce(feeds.updated,feeds.published,'1970-01-01') desc" ) ) end end
items()
click to toggle source
# File lib/newscast.rb, line 192 def self.items connection ## make sure we have a database connection (and setup) up-and-running ## note: always use "multi-site" setup; defaults to 'news' site key ## note: add "default" scope - orders (sorts) by latest / time rec = Pluto::Model::Site.where(key: site).first if rec.nil? Pluto::Model::Item.none ## use null (relation) pattern to avoid crash on nil - why? why not? else rec.items.order( Arel.sql( "coalesce(items.updated,items.published,'1970-01-01') desc" ) ) end end
latest()
click to toggle source
# File lib/newscast.rb, line 205 def self.latest() items; end
month( month=Date.today.month, year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 241 def self.month( month=Date.today.month, year=Date.today.year ) q = "%4d-%02d" % [year,month] # e.g. 2020-01 etc. items. where( Arel.sql( "strftime('%Y-%m', coalesce(items.updated,items.published,'1970-01-01')) = '#{q}'" ) ) end
norm_feed_hash( old_h )
click to toggle source
# File lib/newscast.rb, line 87 def self.norm_feed_hash( old_h ) ## todo/check: rename to normalize/unify_feeds or resolve_feedlist or something? ## unify feed list entries ## case 1) if section name is some thing like [Andrew Kane] ## and NO title/name key than assume it's the title/name ## and auto-generated key/id ## move all "global" settings to [planet] section - why? why not? ## e.g. ## title = Planet Open Data News ## becomes ## [planet] ## title = Planet Open Data News h = {} old_h.each do |k,v| if v.is_a?( String ) h[ k ] = v ## pass along as-is (assume "top-level" / global setting) elsif v.is_a?( Hash ) ## puts "#{k}:" ## pp v ## todo/fix: use "proper" ident e.g. allow 0-9 and .-_ too? why? why not? if k =~ /^[a-z_][a-z0-9$_.]*$/ ## all lower case; assume id - add 0-9 and .-_ - why? why not? h[ k ] = v else ## puts "bingo! section name shortcut - #{k}" if k.start_with?( 'http' ) if v.has_key?( 'feed' ) then raise ArgumentError.new( "duplicate >feed< hash table entry in section >#{k}<; cannot autogen key" ); end new_k = autogen_feed_key( k ) # note: use merge - why? why not? to NOT overwrite existing entry - why? why not? h[ new_k ] = { 'feed' => k }.merge( v ) else ## transform key to title and auto-generate id (new key) if v.has_key?( 'title' ) || v.has_key?( 'name' ) then raise ArgumentError.new( "duplicate >name< or >title< hash table entry in section >#{k}<; cannot autogen key" ); end if v.has_key?( 'feed' ) == false then raise ArgumentError.new( "expected / required >feed< hash table entry missing for section >#{k}<"); end new_k = autogen_feed_key( v['feed'] ) # note: use merge - why? why not? to NOT overwrite existing entry - why? why not? h[ new_k ] = { 'title' => k }.merge( v ) end end else raise ArgumentError.new( "expected String or Hash for value (in hash table) but got >#{v.class.name}< for key >#{k}<" ) end end ## todo/check - auto-add required (?) missing title if missing - why? why not? h['title'] = 'Untitled' if h.has_key?( 'title' ) == false h end
q( quarter=Date.today.quarter, year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 264 def self.q( quarter=Date.today.quarter, year=Date.today.year ) quarter( quarter, year ); end
q1( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 265 def self.q1( year=Date.today.year ) quarter1( year ); end
q2( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 266 def self.q2( year=Date.today.year ) quarter2( year ); end
q3( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 267 def self.q3( year=Date.today.year ) quarter3( year ); end
q4( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 268 def self.q4( year=Date.today.year ) quarter4( year ); end
quarter( quarter=Date.today.quarter, year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 249 def self.quarter( quarter=Date.today.quarter, year=Date.today.year ) case quarter when 1 then between( Date.new( year, 1, 1), Date.new( year, 3, 31) ); when 2 then between( Date.new( year, 4, 1), Date.new( year, 6, 30) ); when 3 then between( Date.new( year, 7, 1), Date.new( year, 9, 30) ); when 4 then between( Date.new( year, 10, 1), Date.new( year,12, 31) ); else raise ArgumentError end end
quarter1( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 259 def self.quarter1( year=Date.today.year ) quarter(1, year); end
quarter2( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 260 def self.quarter2( year=Date.today.year ) quarter(2, year); end
quarter3( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 261 def self.quarter3( year=Date.today.year ) quarter(3, year); end
quarter4( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 262 def self.quarter4( year=Date.today.year ) quarter(4, year); end
refresh()
click to toggle source
# File lib/newscast.rb, line 172 def self.refresh() update; end
render( text, **kwargs )
click to toggle source
# File lib/newscast.rb, line 312 def self.render( text, **kwargs ) template = Template.new( text ) template.render( **kwargs ) end
site()
click to toggle source
# File lib/newscast.rb, line 62 def self.site() @site ||= 'news'; end
site=(value)
click to toggle source
todo/check: allow (add) site = nil for no site “filter” (all items / feeds) - why? why not?
# File lib/newscast.rb, line 61 def self.site=(value) @site = value; end
subscribe( *feeds )
click to toggle source
# File lib/newscast.rb, line 140 def self.subscribe( *feeds ) site_hash = if feeds.size == 1 && feeds[0].is_a?( Hash ) ## puts "bingo! it's a hash" norm_feed_hash( feeds[0] ) elsif feeds.size == 1 && feeds[0].is_a?( String ) && feeds[0] =~ /\n/ ## string includes newline (e.g. more than a single line?) ## if yes, parse and assume ini (config) format norm_feed_hash( INI.load( feeds[0] )) else ## assume list / array of strings (feed_urls) ## puts "bingo! it's a string list" ## auto-build a (simple) site hash feeds.reduce( { ## note: keys are strings (NOT symbols) for now 'title' => 'Untitled' ## todo/check: remove title? required? check in model update if missing? } ) do |h, feed| key = autogen_feed_key( feed ) h[ key ] = { 'feed' => feed } h end end connection ## make sure we have a database connection (and setup) up-and-running ## note: always use "multi-site" setup; defaults to 'news' site key Pluto::Model::Site.deep_create_or_update_from_hash!( site, site_hash ) end
this_month()
click to toggle source
# File lib/newscast.rb, line 283 def self.this_month() month; end
this_quarter()
click to toggle source
# File lib/newscast.rb, line 284 def self.this_quarter() quarter; end
this_week()
click to toggle source
# File lib/newscast.rb, line 282 def self.this_week() week; end
this_year()
click to toggle source
# File lib/newscast.rb, line 285 def self.this_year() year; end
today()
click to toggle source
# File lib/newscast.rb, line 208 def self.today ## todo: order by time!! - possible - why? why not? ## note: use date() to cut-off hours etc. if present? q = Date.today.strftime('%Y-%m-%d') # e.g. 2020-02-20 items. where( Arel.sql( "date(coalesce(items.updated,items.published)) = '#{q}'" ) ) end
update()
click to toggle source
# File lib/newscast.rb, line 168 def self.update connection ## make sure we have a database connection (and setup) up-and-running Pluto.update_feeds end
week( week=Date.today.cweek, year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 230 def self.week( week=Date.today.cweek, year=Date.today.year ) ## note: SQLite only supports "classic" week of year (not ISO "commercial week" starting on monday - and not on sunday) ## %W - week of year: 00-53 ## thus, needs to calculate start and end date!!! start_date = Date.commercial(year, week, 1) end_date = Date.commercial(year, week, 7) between( start_date, end_date ) end
year( year=Date.today.year )
click to toggle source
# File lib/newscast.rb, line 271 def self.year( year=Date.today.year ) q = year items. where( Arel.sql( "strftime('%Y', coalesce(items.updated,items.published,'1970-01-01')) = '#{q}'" ) ) end