forked from MagicMirrorOrg/MagicMirror
-
Notifications
You must be signed in to change notification settings - Fork 0
/
news.js
152 lines (112 loc) · 4 KB
/
news.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// A lot of this code is from the original feedToJson function that was included with this project
// The new code allows for multiple feeds to be used but a bunch of variables and such have literally been copied and pasted into this code and some help from here: http://jsfiddle.net/BDK46/
// The original version can be found here: http://airshp.com/2011/jquery-plugin-feed-to-json/
var news = {
feed: config.news.feed || null,
newsLocation: '.news',
newsItems: [],
seenNewsItem: [],
_yqURL: 'https://query.yahooapis.com/v1/public/yql',
_yqlQS: '?format=json&q=select%20*%20from%20rss%20where%20url%3D',
_cacheBuster: Math.floor((new Date().getTime()) / 1200 / 1000),
_failedAttempts: 0,
fetchInterval: config.news.fetchInterval || 60000,
updateInterval: config.news.interval || 5500,
fadeInterval: 2000,
intervalId: null,
fetchNewsIntervalId: null
}
/**
* Creates the query string that will be used to grab a converted RSS feed into a JSON object via Yahoo
* @param {string} feed The original location of the RSS feed
* @return {string} The new location of the RSS feed provided by Yahoo
*/
news.buildQueryString = function (feed) {
return this._yqURL + this._yqlQS + '\'' + encodeURIComponent(feed) + '\'';
}
/**
* Fetches the news for each feed provided in the config file
*/
news.fetchNews = function () {
// Reset the news feed
this.newsItems = [];
this.feed.forEach(function (_curr) {
var _yqUrlString = this.buildQueryString(_curr);
this.fetchFeed(_yqUrlString);
}.bind(this));
}
/**
* Runs a GET request to Yahoo's service
* @param {string} yqUrl The URL being used to grab the RSS feed (in JSON format)
*/
news.fetchFeed = function (yqUrl) {
$.ajax({
type: 'GET',
datatype:'jsonp',
url: yqUrl,
success: function (data) {
if (data.query.count > 0) {
this.parseFeed(data.query.results.item);
} else {
console.error('No feed results for: ' + yqUrl);
}
}.bind(this),
error: function () {
// non-specific error message that should be updated
console.error('No feed results for: ' + yqUrl);
}
});
}
/**
* Parses each item in a single news feed
* @param {Object} data The news feed that was returned by Yahoo
* @return {boolean} Confirms that the feed was parsed correctly
*/
news.parseFeed = function (data) {
var _rssItems = [];
for (var i = 0, count = data.length; i < count; i++) {
_rssItems.push(data[i].title);
}
this.newsItems = this.newsItems.concat(_rssItems);
return true;
}
/**
* Loops through each available and unseen news feed after it has been retrieved from Yahoo and shows it on the screen
* When all news titles have been exhausted, the list resets and randomly chooses from the original set of items
* @return {boolean} Confirms that there is a list of news items to loop through and that one has been shown on the screen
*/
news.showNews = function () {
// If all items have been seen, swap seen to unseen
if (this.newsItems.length === 0 && this.seenNewsItem.length !== 0) {
if (this._failedAttempts === 20) {
console.error('Failed to show a news story 20 times, stopping any attempts');
return false;
}
this._failedAttempts++;
setTimeout(function () {
this.showNews();
}.bind(this), 3000);
} else if (this.newsItems.length === 0 && this.seenNewsItem.length !== 0) {
this.newsItems = this.seenNewsItem.splice(0);
}
var _location = Math.floor(Math.random() * this.newsItems.length);
var _item = news.newsItems.splice(_location, 1)[0];
this.seenNewsItem.push(_item);
$(this.newsLocation).updateWithText(_item, this.fadeInterval);
return true;
}
news.init = function () {
if (this.feed === null || (this.feed instanceof Array === false && typeof this.feed !== 'string')) {
return false;
} else if (typeof this.feed === 'string') {
this.feed = [this.feed];
}
this.fetchNews();
this.showNews();
this.fetchNewsIntervalId = setInterval(function () {
this.fetchNews()
}.bind(this), this.fetchInterval)
this.intervalId = setInterval(function () {
this.showNews();
}.bind(this), this.updateInterval);
}