-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRSSFeed-Multi.py
180 lines (141 loc) · 5.79 KB
/
RSSFeed-Multi.py
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/python
"""
RSSFeed-Multi.py
Author : Martin Coleman with major contributions by Raspberry Pi forum user ghp
Creation Date : 22/02/2022
Free and open for all to use. But put credit where credit is due.
Use the rocker switch to flip between feeds, button 4 (the one on it's own) will shutdown.
OVERVIEW:-----------------------------------------------------------------------
Obtian data from an RSS feeds and display it on an LCD
"""
import pifacecad
try:
from lcdScroll import Scroller
except ImportError:
print ("Please ensure lcdScroll.py is in the current directory")
try:
import feedparser
except ImportError:
print ("The feedparser module is missing! Please run; sudo pip install feedparser and try again.")
import sys
import threading
import time
import copy
import os
RSS_FEEDS = [
{"feed_name": "BBC News - UK", "url": "http://feeds.bbci.co.uk/news/rss.xml?edition=uk"},
{"feed_name": "BBC News - US", "url": "http://feeds.bbci.co.uk/news/rss.xml?edition=us"},
{"feed_name": "BBC News - Intl", "url": "http://feeds.bbci.co.uk/news/rss.xml?edition=int"},
{"feed_name": "Toms Hardware", "url": "https://www.tomshardware.com/uk/feeds/all"},
{"feed_name": "BBC Weather", "url": "https://weather-broker-cdn.api.bbci.co.uk/en/forecast/rss/3day/3209928"},
{"feed_name": "Pi Blog", "url": "https://www.raspberrypi.org/blog/feed/"},
{"feed_name": "Adafruit", "url": "https://blog.adafruit.com/category/raspberry-pi/feed"},
{"feed_name": "The PiHut", "url": "https://thepihut.com/blogs/raspberry-pi-roundup.atom"},
{"feed_name": "Pimoroni", "url": "https://blog.pimoroni.com/rss/"},
]
class RSSFeed(object):
def __init__(self, feed_name, feed_url):
self.feed_name = feed_name
self.feed_url = feed_url
class FeedViewer:
def __init__(self, cad):
self.cad = cad
self.cad.lcd.backlight_on()
self.cad.lcd.blink_off()
self.cad.lcd.cursor_off()
def start(self, feed):
self.current_feed = feed
self.run = True
self.stopped_event = threading.Event()
self.thread_update = threading.Thread(target=self._update, name="update")
self.thread_update.start()
def stop(self):
self.run = False
self.stopped_event.wait()
self.stopped_event.clear()
def terminate(self):
cad.lcd.blink_off()
cad.lcd.cursor_off()
cad.lcd.backlight_off()
cad.lcd.clear()
def _update(self):
""" running in a thread; rolling feeds to lcd"""
speed_time = 0.01 # How fast to scroll the lcd
current_position = 0
rawfeed=feedparser.parse(self.current_feed.feed_url)
self.cad.lcd.clear()
while self.run:
try:
feed = rawfeed['entries'][current_position]['title']
except Exception:
# most possibly end of feed arrived
current_position = 0
continue
title = self.current_feed.feed_name
lines = [title,feed]
# Create our scroller instance:
scroller = Scroller(lines=lines)
t_end = time.time() + 60 # How long to scroll each entry of the feed, in seconds.
while time.time() < t_end:
if not self.run: break
#Get the updated scrolled lines, and display:
message = scroller.scroll()
self.cad.lcd.write(message)
self._sleep(speed_time)
current_position += 1
self.stopped_event.set()
def _sleep(self, t):
"""a stoppable time.sleep()"""
t_end = time.time() + t
while time.time() < t_end:
if not self.run: break
time.sleep(0.05)
# listener cannot deactivate itself so we have to wait until it has
# finished using a threading.Barrier.
# global end_barrier
end_barrier = threading.Barrier(2)
class RSSController(object):
def __init__(self, cad, feeds, feed_index=0):
self.feeds = feeds
self.feed_index = feed_index
self.lock = threading.Lock()
with self.lock:
self.viewer = FeedViewer(cad)
current_feed = copy.copy( self.feeds[self.feed_index] )
self.viewer.start( current_feed)
def next_feed(self, event=None):
with self.lock:
self.feed_index = (self.feed_index + 1) % len(self.feeds)
self.viewer.stop()
current_feed = copy.copy( self.feeds[self.feed_index] )
self.viewer.start( current_feed)
def previous_feed(self, event=None):
with self.lock:
self.feed_index = (self.feed_index - 1) % len(self.feeds)
self.viewer.stop()
current_feed = copy.copy( self.feeds[self.feed_index] )
self.viewer.start( current_feed)
def stop(self):
with self.lock:
self.viewer.stop()
self.viewer.terminate()
if __name__ == "__main__":
feeds = \
[RSSFeed(s['feed_name'], s['url']) for s in RSS_FEEDS]
cad = pifacecad.PiFaceCAD()
# global rssdisplay
rssdisplay = RSSController(cad, feeds)
# wait for button presses
switchlistener = pifacecad.SwitchEventListener(chip=cad)
switchlistener.register(4, pifacecad.IODIR_ON, end_barrier.wait)
switchlistener.register(6, pifacecad.IODIR_ON, rssdisplay.previous_feed)
switchlistener.register(7, pifacecad.IODIR_ON, rssdisplay.next_feed)
switchlistener.activate()
end_barrier.wait() # wait unitl exit
switchlistener.deactivate()
rssdisplay.stop()
cad.lcd.write("Shutdown In 5")
time.sleep(5)
cad.lcd.clear()
os.system("sudo shutdown -h now")
#sys.exit() # Uncomment this and comment the above to exit rather than shutdown.