Advertisement
Aixler

ps5

Jul 18th, 2013
475
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.77 KB | None | 0 0
  1. # 6.00 Problem Set 5
  2. # RSS Feed Filter
  3.  
  4. import feedparser
  5. import string
  6. import time
  7. from project_util import translate_html
  8. from news_gui import Popup
  9.  
  10. #-----------------------------------------------------------------------
  11. #
  12. # Problem Set 5
  13.  
  14. #======================
  15. # Code for retrieving and parsing
  16. # Google and Yahoo News feeds
  17. # Do not change this code
  18. #======================
  19.  
  20. def process(url):
  21.     """
  22.    Fetches news items from the rss url and parses them.
  23.    Returns a list of NewsStory-s.
  24.    """
  25.     feed = feedparser.parse(url)
  26.     entries = feed.entries
  27.     ret = []
  28.     for entry in entries:
  29.         guid = entry.guid
  30.         title = translate_html(entry.title)
  31.         link = entry.link
  32.         summary = translate_html(entry.summary)
  33.         try:
  34.             subject = translate_html(entry.tags[0]['term'])
  35.         except AttributeError:
  36.             subject = ""
  37.         newsStory = NewsStory(guid, title, subject, summary, link)
  38.         ret.append(newsStory)
  39.     return ret
  40.  
  41. #======================
  42. # Part 1
  43. # Data structure design
  44. #======================
  45.  
  46. # Problem 1
  47.  
  48. # TODO: NewsStory
  49.  
  50. class NewsStory(object):
  51.     def __init__(self, guid, title, subject, summary, link):
  52.         self.guid = guid
  53.         self.title = title
  54.         self.subject = subject
  55.         self.summary = summary
  56.         self.link = link
  57.     def get_guid(self):
  58.         return self.guid
  59.     def get_title(self):
  60.         return self.title
  61.     def get_subject(self):
  62.         return self.subject
  63.     def get_summary(self):
  64.         return self.summary
  65.     def get_link(self):
  66.         return self.link
  67.    
  68. #======================
  69. # Part 2
  70. # Triggers
  71. #======================
  72.  
  73. class Trigger(object):
  74.     def evaluate(self, story):
  75.         """
  76.        Returns True if an alert should be generated
  77.        for the given news item, or False otherwise.
  78.        """
  79.         raise NotImplementedError
  80.  
  81. # Whole Word Triggers
  82. # Problems 2-5
  83.  
  84. # TODO: WordTrigger
  85. class WordTrigger(Trigger):
  86.     def __init__(self, word):
  87.         self.word = word.lower()
  88.     def is_word_in(self, text):
  89.         self.text = text
  90.         self.text = self.text.lower()
  91.         for c in string.punctuation:
  92.             self.text = self.text.replace(c,' ')
  93.         self.text = self.text.split()
  94.         if self.word in self.text:
  95.             return True
  96.         else:
  97.             return False
  98.  
  99. # TODO: TitleTrigger
  100. # TODO: SubjectTrigger
  101. # TODO: SummaryTrigger
  102.  
  103. class TitleTrigger(WordTrigger):
  104.     def evaluate(self, story):
  105.         return self.is_word_in(story.get_title())
  106.  
  107. class SubjectTrigger(WordTrigger):
  108.     def evaluate(self, story):
  109.         return self.is_word_in(story.get_subject())
  110.  
  111. class SummaryTrigger(WordTrigger):
  112.     def evaluate(self, story):
  113.         return self.is_word_in(story.get_summary())
  114.  
  115. # Composite Triggers
  116. # Problems 6-8
  117.  
  118. # TODO: NotTrigger
  119. # TODO: AndTrigger
  120. # TODO: OrTrigger
  121.  
  122. class NotTrigger(Trigger):
  123.     def __init__(self, other):
  124.         self.other = other
  125.     def evaluate(self, story):
  126.         if not self.other.evaluate(story):
  127.             return True
  128.         else:
  129.             return False
  130.        
  131. class AndTrigger(Trigger):
  132.     def __init__(self, other1, other2):
  133.         self.other1 = other1
  134.         self.other2 = other2
  135.     def evaluate(self, story):
  136.         if self.other1.evaluate(story) and self.other2.evaluate(story):
  137.             return True
  138.         else:
  139.             return False
  140.        
  141. class OrTrigger(Trigger):
  142.     def __init__(self, other1, other2):
  143.         self.other1 = other1
  144.         self.other2 = other2
  145.     def evaluate(self, story):
  146.         if self.other1.evaluate(story) or self.other2.evaluate(story):
  147.             return True
  148.         else:
  149.             return False
  150.  
  151. # Phrase Trigger
  152. # Question 9
  153.  
  154. # TODO: PhraseTrigger
  155.  
  156. class PhraseTrigger(Trigger):
  157.     def __init__(self, phrase):
  158.         self.phrase = phrase
  159.     def evaluate(self, story):
  160.         if self.phrase in story.get_title() or \
  161.            self.phrase in story.get_subject() or \
  162.            self.phrase in story.get_summary():
  163.             return True
  164.         else:
  165.             return False
  166.            
  167. #======================
  168. # Part 3
  169. # Filtering
  170. #======================
  171.  
  172. def filter_stories(stories, triggerlist):
  173.     """
  174.    Takes in a list of NewsStory-s.
  175.    Returns only those stories for whom
  176.    a trigger in triggerlist fires.
  177.    """
  178.     # TODO: Problem 10
  179.     # This is a placeholder (we're just returning all the stories, with no filtering)
  180.     # Feel free to change this line!
  181.     filtered_stories = []
  182.    
  183.     for i in stories:
  184.         for f in triggerlist:
  185.             if f.evaluate(i) is True:
  186.                 print i.get_title()
  187.                 filtered_stories.append(i)
  188.                 break
  189.    
  190.     return filtered_stories
  191.  
  192. ##story = NewsStory(12,'Why do apples grow on trees?', 'Fruit', 'Because they do', 'link')
  193. ##text = 'Apples, and trees" and nature stuff!'
  194. ##word = 'do'
  195. ##test3 = TitleTrigger(word)
  196. ##test4 = SubjectTrigger(word)
  197. ##test5 = SummaryTrigger(word)
  198. ##test6 = NotTrigger(TitleTrigger(word))
  199. ##test7 = AndTrigger(TitleTrigger(word),SubjectTrigger(word))
  200. ##test8 = OrTrigger(TitleTrigger(word),SummaryTrigger(word))
  201. ##print 'text',test3.is_word_in(text)
  202. ##print 'title',test3.evaluate(story)
  203. ##print 'subject',test4.evaluate(story)
  204. ##print 'summary',test5.evaluate(story)
  205. ##print 'not=', test6.evaluate(story)
  206. ##print 'and=', test7.evaluate(story)
  207. ##print 'or=', test8.evaluate(story)
  208.  
  209. #======================
  210. # Part 4
  211. # User-Specified Triggers
  212. #======================
  213.  
  214. def readTriggerConfig(filename):
  215.     """
  216.    Returns a list of trigger objects
  217.    that correspond to the rules set
  218.    in the file filename
  219.    """
  220.     # Here's some code that we give you
  221.     # to read in the file and eliminate
  222.     # blank lines and comments
  223.     triggerlist = []
  224.     triggerkeys = {}
  225.     triggered = []
  226.     triggerfile = open(filename, "r")
  227.     all = [ line.rstrip() for line in triggerfile.readlines() ]
  228. ##    print 'all=', all
  229.     lines = []
  230.     for line in all:
  231.         if len(line) == 0 or line[0] == '#':
  232.             continue
  233.         lines.append(line)
  234. ##    print 'lines=', lines
  235.  
  236.     for i in range(len(lines)):
  237.         triggerlist.append(lines[i].split())
  238. ##    print 'sep=', triggerlist
  239.    
  240.     for i in range(len(triggerlist)):
  241.         if triggerlist[i][1] == 'TITLE':
  242.             print 'title=', triggerlist[i][2]
  243.             triggerkeys[triggerlist[i][0]] = TitleTrigger(triggerlist[i][2])
  244.         elif triggerlist[i][1] == 'SUBJECT':
  245.             triggerkeys[triggerlist[i][0]] = SubjectTrigger(triggerlist[i][2])  
  246.         elif triggerlist[i][1] == 'SUMMARY':
  247.             print 'summary=', triggerlist[i][2]
  248.             triggerkeys[triggerlist[i][0]] = SummaryTrigger(triggerlist[i][2])  
  249.         elif triggerlist[i][1] == 'NOT':
  250.             triggerkeys[triggerlist[i][0]] = NotTrigger(triggerlist[i][2])
  251.         elif triggerlist[i][1] == 'PHRASE':
  252.             stitch = ''
  253.             for w in triggerlist[i][2:]:
  254.                 if w == triggerlist[i][2]:
  255.                     stitch = stitch + w
  256.                 else:
  257.                     stitch = stitch + ' ' + w
  258.             print 'stitch=', stitch
  259.             triggerkeys[triggerlist[i][0]] = PhraseTrigger(stitch)  
  260.         elif triggerlist[i][1] == 'AND':
  261.             triggerkeys[triggerlist[i][0]] = AndTrigger(triggerkeys[triggerlist[i][2]],triggerkeys[triggerlist[i][3]])
  262.         elif triggerlist[i][1] == 'OR':
  263.             triggerkeys[triggerlist[i][0]] = OrTrigger(triggerkeys[triggerlist[i][2]],triggerkeys[triggerlist[i][3]])
  264.         elif triggerlist[i][0] == 'ADD':
  265.             for t in triggerlist[i]:
  266. ##                print t
  267.                 if t in triggerkeys:
  268. ##                    print 'is a key'
  269.                     triggered.append(triggerkeys[t])
  270. ##    print 'trigkey=', triggerkeys
  271. ##    print 'triggered=',  triggered                              
  272.        
  273.  
  274.     return triggered
  275.     # TODO: Problem 11
  276.     # 'lines' has a list of lines you need to parse
  277.     # Build a set of triggers from it and
  278.     # return the appropriate ones
  279.    
  280. ##t1 = TitleTrigger("Obama")
  281. ##t2 = SummaryTrigger("MIT")
  282. ##t3 = PhraseTrigger("Bombing")
  283. ##t4 = OrTrigger(t2, t3)
  284. ##triggerlist = [t1, t4]
  285. ##print 'trig=', triggerlist
  286.  
  287. import thread
  288.  
  289. def main_thread(p):
  290.     # A sample trigger list - you'll replace
  291.     # this with something more configurable in Problem 11
  292. ##    t1 = TitleTrigger("Obama")
  293. ##    t2 = SummaryTrigger("MIT")
  294. ##    t3 = PhraseTrigger("Bombing")
  295. ##    t4 = OrTrigger(t2, t3)
  296. ##    triggerlist = [t1, t4]
  297. ##    print 'triggerlist=', triggerlist
  298.    
  299.     # TODO: Problem 11
  300.     # After implementing readTriggerConfig, uncomment this line
  301.     triggerlist = readTriggerConfig("triggers.txt")
  302.  
  303.     guidShown = []
  304.    
  305.     while True:
  306.         print "Polling..."
  307.  
  308.         # Get stories from Google's Top Stories RSS news feed
  309.         stories = process("http://news.google.com/?output=rss")
  310.         # Get stories from Yahoo's Top Stories RSS news feed
  311.         stories.extend(process("http://rss.news.yahoo.com/rss/topstories"))
  312.  
  313.         # Only select stories we're interested in
  314.         stories = filter_stories(stories, triggerlist)
  315.    
  316.         # Don't print a story if we have already printed it before
  317.         newstories = []
  318.         for story in stories:
  319.             if story.get_guid() not in guidShown:
  320.                 newstories.append(story)
  321.        
  322.         for story in newstories:
  323.             guidShown.append(story.get_guid())
  324.             p.newWindow(story)
  325.  
  326.         print "Sleeping..."
  327.         time.sleep(SLEEPTIME)
  328.  
  329. SLEEPTIME = 60 #seconds -- how often we poll
  330. if __name__ == '__main__':
  331.     p = Popup()
  332.     thread.start_new_thread(main_thread, (p,))
  333.     p.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement