Skip to content

Instantly share code, notes, and snippets.

@rdempsey
Forked from toddq/README.md
Last active October 13, 2022 07:03
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rdempsey/8a8c98848f147d6d3a1a to your computer and use it in GitHub Desktop.
Save rdempsey/8a8c98848f147d6d3a1a to your computer and use it in GitHub Desktop.

##Description Simple Dashing widget (and associated job) to display RSS feeds. Based on toddq's News widget. Due to comments about the widget not working for many sites I updated the widget to use Ruby's RSS library. It works quite well now.

##Screenshot

##Dependencies nokogiri

htmlentities

Add it to dashing's gemfile:

gem 'nokogiri'
gem 'htmlentities'

and run bundle install.

##Usage To use this widget, copy news.html, news.coffee, and news.scss into the /widgets/news directory. Put the news.rb file in your /jobs folder.

To include the widget in a dashboard, add the following snippet to the dashboard layout file:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
  <div data-id="seattle-times" data-view="News" data-title="Seattle Times" data-interval="30"></div>
</li>

At the top of the news.rb job file, add any rss feed urls you want fetched to the hash, and the widget id to send data to. In the dashboard layout file, the optional data-interval binding can be used to specify how frequently to rotate the news items.

class Dashing.News extends Dashing.Widget
ready: ->
@currentIndex = 0
@headlineElem = $(@node).find('.headline-container')
@nextComment()
@startCarousel()
onData: (data) ->
@currentIndex = 0
startCarousel: ->
interval = $(@node).attr('data-interval')
interval = "30" if not interval
setInterval(@nextComment, parseInt( interval ) * 1000)
nextComment: =>
headlines = @get('headlines')
if headlines
@headlineElem.fadeOut =>
@currentIndex = (@currentIndex + 1) % headlines.length
@set 'current_headline', headlines[@currentIndex]
@headlineElem.fadeIn()
<div class="heading" data-bind="title"></div>
<div class="headline-container">
<h1 class="title" data-bind="current_headline.title | raw"></h1>
<div class="headline description" data-bind="current_headline.description | raw"></div>
</div>
require 'rss'
require 'open-uri'
require 'nokogiri'
require 'htmlentities'
news_feeds = {
"bbc-tech" => "http://feeds.bbci.co.uk/news/technology/rss.xml",
"mashable" => "http://feeds.feedburner.com/Mashable",
"techcrunch" => "http://feeds.feedburner.com/TechCrunch/",
"opm" => "http://www.opm.gov/rss/operatingstatus.atom",
}
Decoder = HTMLEntities.new
class News
def initialize(widget_id, feed)
@widget_id = widget_id
@feed = feed
end
def widget_id()
@widget_id
end
def truncate(string, length = 200)
raise 'Truncate: Length should be greater than 3' unless length > 3
truncated_string = string.to_s
if truncated_string.length > length
truncated_string = truncated_string[0...(length - 3)]
truncated_string += '...'
end
truncated_string
end
def latest_headlines()
news_headlines = []
open(@feed) do |rss|
feed = RSS::Parser.parse(rss)
feed.items.each do |item|
title = clean_html(item.title.to_s)
begin
summary = truncate(clean_html(item.description))
rescue
doc = Nokogiri::HTML(item.summary.content)
summary = truncate((doc.xpath("//text()").remove).to_s)
end
news_headlines.push({ title: title, description: summary })
end
end
news_headlines
end
def clean_html( html )
html = html.gsub(/<\/?[^>]*>/, "")
html = Decoder.decode( html )
return html
end
end
@News = []
news_feeds.each do |widget_id, feed|
begin
@News.push(News.new(widget_id, feed))
rescue Exception => e
puts e.to_s
end
end
SCHEDULER.every '60m', :first_in => 0 do |job|
@News.each do |news|
headlines = news.latest_headlines()
send_event(news.widget_id, { :headlines => headlines })
end
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #FF9500;
$value-color: #fff;
$title-color: rgba(255, 255, 255, 0.7);;
$moreinfo-color: rgba(255, 255, 255, 0.8);;
// ----------------------------------------------------------------------------
// Widget-news styles
// ----------------------------------------------------------------------------
.widget-news {
background-color: $background-color;
vertical-align: baseline !important;
.headline-container {
display: none;
}
.title {
font-size: 1.2em;
}
.description {
font-size: 0.8em;
color: $moreinfo-color;
}
.heading{
color: black;
}
}
@charlievogt
Copy link

Excellent! This works well for me for news, but I'm wondering if someone could assist me with an additional application. I have a box at work that plays streaming music, and it has an RSS feed that I can subscribe to (either RSS or Atom, actually), and I'd love to use this to post the current song on the dashboard. Unfortunately, I'm an amateur when it comes to RSS/atom...I have no clue how to adjust the widget to get it to grab the right data. Any suggestions?

Thanks!

Atom:

<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>DEVICENAME</title>
    <id>DEVICEID</id>
    <link href="http://manufacturerlink" />
    <icon>/rss/icon.ico</icon>
    <logo>/rss/logo.png</logo>
    <updated>2015-04-13T13:05:29-0500</updated>
    <author>
        <name>BOXNAME</name>
    </author>
    <rights>Copyright © 2014 Corporation All rights reserved.</rights>
    <entry>
        <id>urn:uuid:Disregard1</id>
        <title>Time To Pretend by Jingle Punks Hipster Orchestra on Hipster Dinner Party Vol. 1</title>
        <content>zoneName: Zone 1, zoneType: streamingservice, trackTitle: Time To Pretend, trackArtist: Jingle Punks Hipster Orchestra, trackAlbum: Hipster Dinner Party Vol. 1, trackLength: 207, trackPosition: 36</content>
    </entry>
</feed>

RSS:

<?xml version="1.0"?>
<rss version="2.0">
    <channel>
        <title>DEVICENAME</title>
        <link>http://manufacturerlink"</link>
        <image>
            <url>/rss/logo.png</url>
        </image>
        <lastBuildDate>2015-04-13T13:10:33-0500</lastBuildDate>
        <item>
            <title>If I Had A Boat (Live) by Lyle Lovett on Live In Texas</title>
            <description>zoneName: Zone 1, zoneType: streamingservice, trackTitle: If I Had A Boat (Live), trackArtist: Lyle Lovett, trackAlbum: Live In Texas, trackLength: 199, trackPosition: 132</description>
        </item>
    </channel>
</rss>

@vandadck
Copy link

Out of the box, this does not display the latest item in a feed. To fix this I had to change the @CurrentIndex from 0 to -1

ready: ->
@CurrentIndex = -1
[...]

onData: (data) ->
@CurrentIndex = -1

@nils-me
Copy link

nils-me commented Nov 14, 2015

Hi!
I can you please write a code to make this display two or three news at the same time?

@sielay
Copy link

sielay commented Sep 13, 2016

Some feeds doesn't have titles. I made such change to make it work

require 'rss'
require 'open-uri'
require 'nokogiri'
require 'htmlentities'

news_feeds = {
  "confess" => "http://www.codingconfessional.com/feed.rss",
}

Decoder = HTMLEntities.new

class News
  def initialize(widget_id, feed)
    @widget_id = widget_id
    @feed = feed
  end

  def widget_id()
    @widget_id
  end

  def truncate(string, length = 200)
    raise 'Truncate: Length should be greater than 3' unless length > 3

    truncated_string = string.to_s
    if truncated_string.length > length
      truncated_string = truncated_string[0...(length - 3)]
      truncated_string += '...'
    end
    truncated_string
  end

  def latest_headlines()
    news_headlines = []
    open(@feed) do |rss|
      feed = RSS::Parser.parse(rss, false)
      feed.items.each do |item|
        summary = clean_html(item.content.to_s)
        news_headlines.push({ title: "", description: summary })
      end
    end
    news_headlines
  end

  def clean_html( html )
    html = html.gsub(/<\/?[^>]*>/, "")
    html = Decoder.decode( html )
    return html
  end

end

@News = []
news_feeds.each do |widget_id, feed|
  begin
    @News.push(News.new(widget_id, feed))
  rescue Exception => e
    puts e.to_s
  end
end

SCHEDULER.every '5m', :first_in => 0 do |job|
  @News.each do |news|
    headlines = news.latest_headlines()
    send_event(news.widget_id, { :headlines => headlines })
  end
end

@MrBenzim
Copy link

Hi all,
this widget does not work for many RSS feeds for me. For example some german feeds:
http://www.tagesschau.de/xml/rss2 or http://www.spiegel.de/schlagzeilen/tops/index.rss
Is it possible that the widget is not compatible to RSS 2.0 feeds?
Can anybody reproduce the issue?

Best regards

@xxgeoffreyxx
Copy link

xxgeoffreyxx commented Jan 12, 2017

How do you declare the widget ID in the top of news.rb?
EDIT
Ignore me, didn't understand the purpose of "seatle-times" until I read the source code of the original

@skyzo35
Copy link

skyzo35 commented Jan 20, 2017

I tried to use this widget but everytime i use it, my dashboard doesn't dispay the dashboard in the right way.
I only have this issue when i keep the news.coffee file...
sans titre

@hostingnuggets
Copy link

It would be nice if this widget could just fetch the last X (to be defined in jobs/news.rb file) news and not all news. For example I am only interested in the last 3 most recent news in an RSS feed.

@7k50
Copy link

7k50 commented Jul 15, 2017

@MrBenzim
I'm also having problems with many RSS feeds, for instance the confess one mentioned on this page. Some work, like bbc-tech.

@NiewWha
Copy link

NiewWha commented Oct 16, 2018

Hello, how is the data getting to the dashboard?
What is the meaning of:

add any rss feed urls you want fetched to the hash, and the widget id to send data to

I thought I just have to add the RSS links to the news.rb file, but it seems not enough. What do I have to do to get the news from my RSS feeds? Is this widget not getting itself the content?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment