Beispiel #1
0
import webbrowser
import tkinter as tk
from controller.utilities import logger

mv_logger = logger('view.main_view')


class MainView(tk.Frame):
    """ Class for view.main_view creates, displays, modifies and receives input from the user interface """

    entry_title = "Welcome to Tiny Ticker news feed"
    entry_link = "https://github.com/int-thumbWar-1-2-3-4/Python-RSS-ticker"

    def __init__(self, master=None):
        """ Constructor for view.main_view.MainView. """

        mv_logger.debug('MainView.__init__')

        super().__init__(master)
        self.master = master
        self.content_label = tk.Label(self, cursor="gumby")

        self.pack()
        self.build_window()
        self.display_entry(self.entry_title, self.entry_link)
        self.menu_bar()

    def menu_bar(self):
        """ View.main_view.MainView.menu_bar adds a drop down menu for our tk window. """

        mv_logger.debug('MainView.menubar')
Beispiel #2
0
import feedparser
from typing import List
from model.article import Article
from controller.utilities import logger

f_logger = logger('model.feed')


class Feed:
    # A collection of articles from a single feed.

    def __init__(self, name: str, list_of_articles: List[Article]):
        # Will not create with empty list

        f_logger.debug('Feed.__init__')

        if len(list_of_articles) == 0:
            # TODO: Make this create an exception if the list is empty
            pass

        self.name: str = name

        self.__list_of_articles: List[Article] = list_of_articles

        self.__sort()
        self.__current_article_index: int = 0

    def __sort(self):
        # Sorts all of the articles on this feed from newest to oldest. Uses the insertion sort process.

        #   Refactored from code at:
Beispiel #3
0
"""
model.article

An object which hold the relevant data for a single feed entry.
"""

from datetime import datetime
from controller.utilities import logger

a_logger = logger('model.article')


class Article:
    """
    model.article.Article

    A single feed entry, i.e. a single news article.
    """

    def __init__(self, title: str, link: str, published_date: datetime):
        """
        Article.__init__

        Arguments:
            title -- the title of the entry. It describes what the article is about.
            link -- the url for the entry itself.
            published_date -- the date and time in which the article was published.
        """

        a_logger.debug('Article.__init__')
Beispiel #4
0
    def test_logger(self):
        """ Unit test for controller.utilities.logger. Should return a Logger object """

        result = logger('name')
        self.assertTrue(isinstance(result, lg.Logger))
Beispiel #5
0
"""
controller.tiny_ticker

Contains methods for mediating communication between this application's modules. It also initializes
and runs the Tiny Ticker application.
"""

import threading
from model import parser
from typing import List
from model.article import Article
from view.main_view import start_main_view, MainView
from model.feed_manager import create_feed_manager, FeedManager
from controller.utilities import logger, ticker_argument_parser

tt_logger = logger('controller.tiny_ticker')

arguments = ticker_argument_parser()


def ten_second_loop(main_view: MainView, cycle, feed_manager: FeedManager):
    """
    controller.tiny_ticker.ten_second_loop

    Switches the display every <cycle> seconds. This function spans a timed looping thread. Every 'cycle' seconds this
    function calls it's self to continue the loop. It is a daemon thread so it acts in the background and it calls
    controller.title_loop.call_switch_display.

    Arguments:
        main_view -- the MainView which displays articles.
        cycle -- the amount of time between view changes. User input from the command line.
Beispiel #6
0
#https://github.com/Jhawk1196/CS3250PythonProject/blob/dev/src/parser.py
from controller.utilities import logger
from bs4 import BeautifulSoup
import requests
import re

p_logger = logger('model.parser')


def parse_url_feed(url):

    p_logger.debug('parser_url_feed')

    feed = []
    if not check_url(url):
        return "Invalid URL. Must Be a RSS Feed URL ending in .rss, .html, or .xml"
    response = requests.get(url)
    parse_value = find_parser(response)
    soup = BeautifulSoup(response.content, parse_value)
    # print(soup.prettify())
    if soup.rss is not None:
        tag = soup.rss
        tag = tag.channel
        for title in tag.find_all(re.compile("title")):
            for entry in title.find_all(string=True):
                feed.append(entry)
    elif soup.find_all(re.compile("atom")) is not None:
        tag = soup.feed
        for entry in tag.find_all("entry"):
            for title in entry.find_all("title"):
                for string in title.find_all(string=True):
!!! At this moment the parser only has a dummy method for .atom feed parsing and cannot actually parse them !!!

rss v2.0 specs can be found here: https://cyber.harvard.edu/rss/rss.html#hrelementsOfLtitemgt
atom v1.0 specs can be found here: https://support.google.com/merchants/answer/160593?hl=en
"""

from email import utils
import requests
from re import search
from bs4 import BeautifulSoup
from typing import List
from datetime import datetime
from model.article import Article
from controller.utilities import logger

p_logger = logger('model.parser.py')


class InvalidRssException(Exception):
    """
    model.parser.InvalidRssException

    Exception raised if an Rss feed is not correctly formatted.
    """
    pass


class InvalidUrlException(Exception):
    """
    model.parser.InvalidUrlException
import feedparser
from typing import List
from model.feed import Feed
from model.article import Article
from controller.utilities import logger

fm_logger = logger('model.feed_manager')


class FeedManagerEmptyError(Exception):
    pass


class FeedNotFoundError(Exception):
    pass


class FeedManager:
    # Holds all of the feeds this instance of Python-RSS-Ticker displays. Manages ordering of Articles so they rotate
    #       between feeds and repeat Articles as little as possible.

    def __init__(self):

        fm_logger.debug('FeedManager.__init__')

        self.__list_of_feeds: List[Feed] = list()
        self.__current_feed_index: int = -1

    def __get_feed(self, feed_name: str) -> Feed:
        # Gets the feed which matches the given name. May return None if match could not be found.