-
Notifications
You must be signed in to change notification settings - Fork 24
Victoria_Kondrat'eva_sam.kondrateva@gmail.com #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Victoria-Sam
wants to merge
10
commits into
epam-python-courses-7-bsu:master
Choose a base branch
from
Victoria-Sam:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
33f8584
Iteartion I initial commit
Victoria-Sam 8377ded
Iteration I:
Victoria-Sam a57ca3b
Second Iteration
Victoria-Sam a646318
Third iteration in process...
Victoria-Sam b0b343e
Tests to third iteration.
Victoria-Sam 59f8bcb
Fourth iteration
Victoria-Sam 035a4fc
Fourth iteration fixed
Victoria-Sam 3e603d5
Fifth iteration
Victoria-Sam 1710df7
fixed README
Victoria-Sam 172c095
last minutes...fixed module import
Victoria-Sam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Byte-compiled / optimized / DLL files | ||
| __pycache__/ | ||
| *.py[cod] | ||
|
|
||
| # C extensions | ||
| *.so | ||
|
|
||
| # Distribution / packaging | ||
| bin/ | ||
| build/ | ||
| develop-eggs/ | ||
| dist/ | ||
| eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
| var/ | ||
| *.egg-info/ | ||
| .installed.cfg | ||
| *.egg | ||
|
|
||
| # Installer logs | ||
| pip-log.txt | ||
| pip-delete-this-directory.txt | ||
|
|
||
| # Unit test / coverage reports | ||
| .tox/ | ||
| .coverage | ||
| .cache | ||
| nosetests.xml | ||
| coverage.xml | ||
|
|
||
| # Translations | ||
| *.mo | ||
|
|
||
| # Mr Developer | ||
| .mr.developer.cfg | ||
| .project | ||
| .pydevproject | ||
|
|
||
| # Rope | ||
| .ropeproject | ||
|
|
||
| # Django stuff: | ||
| *.log | ||
| *.pot | ||
|
|
||
| # Sphinx documentation | ||
| docs/_build/ | ||
|
|
||
| Test_file.json |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,110 @@ | ||
| # Your readme here | ||
| Some text. | ||
| Checkout how to write this file using *markdown*. | ||
| #The best RSS-reader! | ||
| Program is named rss_reader.py. | ||
| ##Instalation | ||
| The recommended way to install rss-reader is with pip: | ||
| * pip install rss_reader-5.0.tar.gz - for Windows | ||
| * sudo pip install rss_reader-5.0.tar.gz - for Linux and Mac | ||
|
|
||
| ##Description and Functions | ||
| ``` | ||
| usage: rss_reader.py [-h] [--limit LIMIT] [--version] [--json] [--verbose] | ||
| [--date DATE] [--to_pdf TO_PDF] [--to_epub TO_EPUB] | ||
| [--colorize] | ||
| [source] | ||
|
|
||
| Pure Python command-line RSS reader. | ||
|
|
||
| positional arguments: | ||
| source RSS URL | ||
|
|
||
| optional arguments: | ||
| -h, --help show this help message and exit | ||
| --limit LIMIT Limit news topics if this parameter provided | ||
| --version Print version info | ||
| --json Print result as JSON in stdout | ||
| --verbose Outputs verbose status messages | ||
| --date DATE Return news from cache with that date | ||
| --to_pdf TO_PDF Conversion of news in the pdf format | ||
| --to_epub TO_EPUB Conversion of news in the epub format | ||
| --colorize Print news in colorized mode in stdout | ||
| ``` | ||
|
|
||
| To run the program from the command line, you must write the file name and string with URL-address of news site. | ||
|
|
||
| It's print a brief description of the news information that appeared on the news site in human-readable | ||
| format and save them in cache. | ||
|
|
||
| Example: | ||
| ```python rss_reader.py "https://news.yahoo.com/rss/" --limit 1 | ||
|
|
||
| Feed: Yahoo News - Latest News & Headlines | ||
|
|
||
| Updated: Sun, 24 Nov 2019 21:19:04 GMT | ||
|
|
||
| Version: rss20 | ||
| -------------------------------------------------------- | ||
| Title: Ukraine's President Zelensky said he didn't feel pressured by Trump. Here | ||
| 's why that's bogus. | ||
| Date: Sat, 23 Nov 2019 08:57:00 -0500 | ||
| Link: https://news.yahoo.com/ukraines-president-zelensky-said-didnt-135700678.ht | ||
| ml | ||
| Summary: [Image: Ukraine's President Zelensky said he didn't feel pressured by | ||
| Trump. Here's why that's bogus.] The US government's assistance to Ukraine is vi | ||
| tal as it contends with an ongoing conflict with pro-Russian separatists in the | ||
| Donbas region. | ||
| Source of image: http://l2.yimg.com/uu/api/res/1.2/3h5JxcDjAP1pHR6KUD2JMQ--/YXBw | ||
| aWQ9eXRhY2h5b247aD04Njt3PTEzMDs-/https://media.zenfs.com/en-US/business_insider_ | ||
| articles_888/7a21ff2ee09c3b4285094c4e64e9602c | ||
| ``` | ||
| ###Nice features | ||
| To please the eyes you can read news from console in a colorful format. | ||
| For this enter such parameter like --colorize and enjoy. | ||
|
|
||
| But this parameter work only for MAC and Linux console. | ||
|
|
||
| ###How to read saving news: | ||
| If you want to read saved news of a certain date, you must enter a --date in %Y%m%d format and the program will work | ||
| without any connecting to the Internet. | ||
|
|
||
| It is also possible to select news from a specific source of a certain date, for this you must enter the url-address | ||
| and --date that you want. | ||
|
|
||
| ###What formats can you convert to? How to do it. | ||
| Program can convert news in ```--to_pdf``` and ```--to_epub``` format. | ||
| Specify the path to the file yourself. Also program convert news in ```--json``` format | ||
| but print result as JSON in stdout. | ||
|
|
||
| JSON format example: | ||
| ```json | ||
| [ | ||
| { | ||
| "Feed": "Yahoo", | ||
| "Updated": "Fri, 08 Nov 2019 17:04:06 GMT", | ||
| "Version": "rss20" | ||
| }, | ||
| { | ||
| "Title": "Some title", | ||
| "Date": "Thu, 07 Nov 2019 09:59:52 -0500", | ||
| "Summary": "Some summary", | ||
| "Link": "Link to news", | ||
| "Image": "Some image information" | ||
| } | ||
| ] | ||
| ``` | ||
| #####Ways for converting: | ||
| - *You can convert from cache* | ||
|
|
||
| For this case news conversion is not depend on internet. | ||
| With ```rss_reader.py --date 20191117 --limit 1 --to_pdf /folder1/folder2/file_name.pdf``` one news for the specified day | ||
| would be converted (the same with ```--to_epub```) and would be generated or overwritten file 'file_name.pdf' | ||
| in folder what you choose. | ||
|
|
||
| - *You can convert news from the Internet* | ||
|
|
||
| For this case Internet is required. | ||
| With ```rss_reader.py https://news.yahoo.com/rss/ --limit 1 --to_pdf /folder1/folder2/file_name.pdf``` one news | ||
| from specified link would be converted (the same with ```--to_epub```)and would be generated or overwritten | ||
| file 'file_name.epub' in folder what you choose. | ||
|
|
||
|
|
||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import json | ||
| import os.path | ||
| import logging | ||
|
|
||
|
|
||
| class NewsCache: | ||
| """Class which create json-file with cached news, | ||
| saved all fresh news and return them with certain date | ||
| and from certain url-address if such url will be introduced.""" | ||
|
|
||
| def __init__(self, file_name): | ||
| self.logger = logging.getLogger(__name__) | ||
| self.file_name = file_name | ||
| self.logger.info("Check for cache file...") | ||
| if os.path.isfile(file_name): | ||
| try: | ||
| with open(file_name, "r") as json_file: | ||
| self.cache_news = json.load(json_file) | ||
| self.logger.info("Reading cache file...") | ||
| except Exception as ex: | ||
| self.logger.error("Error reading file: {} {}".format(type(ex), ex)) | ||
| self.cache_news = {} | ||
| else: | ||
| self.logger.warning("Warning! Caching file is not found!") | ||
| self.cache_news = {} | ||
|
|
||
| def caching(self, all_news, url): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here and below: please use more informative method names |
||
| """Function which create JSON-file | ||
| and save news.""" | ||
| for dictionary in all_news: | ||
| date_in_news = dictionary.pop('Date key') | ||
| title = dictionary['Title'] | ||
| self.cache_news.setdefault(date_in_news, {}).setdefault(url, {}).setdefault(title, dictionary) | ||
| with open(self.file_name, "w") as file_to_write: | ||
| self.logger.info("News caching...") | ||
| file_to_write.write(json.dumps(self.cache_news)) | ||
|
|
||
| def returning(self, desired_date, desired_url=None): | ||
| """Function which return news from cache-file with certain date | ||
| and from certain url-address if such url will be introduced.""" | ||
| self.logger.info('News search in cache...') | ||
| caching_news_list = [] | ||
| if desired_url is not None: | ||
| caching_news_list = list(self.cache_news.get(desired_date, {}).get(desired_url, {}).values()) | ||
| else: | ||
| answer = self.cache_news.get(desired_date, {}) | ||
| for title in answer.values(): | ||
| caching_news_list += title.values() | ||
| return caching_news_list | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| import datetime | ||
| import feedparser | ||
| import logging | ||
| from bs4 import BeautifulSoup | ||
| from RSSReaderException import RSSReaderException | ||
| from NewsCache import NewsCache | ||
| from unidecode import unidecode | ||
| from output import get_output_function | ||
|
|
||
| CACHE_FILE_NAME = "Cache file.json" | ||
|
|
||
|
|
||
| class RSSReader: | ||
|
|
||
| def __init__(self, date, url, limit, is_json, pdf_file_name, epub_file_name, color): | ||
| self.cache = NewsCache(CACHE_FILE_NAME) | ||
| self.date = date | ||
| self.url = url | ||
| self.is_json = is_json | ||
| self.limit = limit | ||
| self.pdf_file_name = pdf_file_name | ||
| self.epub_file_name = epub_file_name | ||
| self.color = color | ||
| self.logger = logging.getLogger(__name__) | ||
|
|
||
| def url_parsing(self): | ||
| parsed_url = feedparser.parse(self.url) | ||
| if parsed_url.status != 200: # URL-access check | ||
| self.logger.error("Can't load RSS feed.") | ||
| raise RSSReaderException('RSS-reader failed. Status: {}.'.format(parsed_url.status)) | ||
| else: | ||
| self.logger.info('RSS parsed successfully!') | ||
| return parsed_url | ||
|
|
||
| def information_about_site(self, parsed_url): | ||
| """Function which make dictionary with data of website""" | ||
| date = parsed_url.get('updated', str(datetime.datetime.now())) | ||
| return { | ||
| 'Feed': unidecode(parsed_url['feed']['title']), | ||
| 'Updated': date, | ||
| 'Version': unidecode(parsed_url['version']), | ||
| } | ||
|
|
||
| def make_news_data(self, news): | ||
| """ | ||
| Function which parsed HTML summary of news and make dictionary with all the necessary news data. | ||
| :return dictionary | ||
| """ | ||
| image_link = 'No image' | ||
| if 'summary' in news: | ||
| # convert_to_epub(news['summary']) | ||
| bs = BeautifulSoup(news['summary'], 'html.parser') | ||
| img = bs.find_all('img') | ||
| if img: | ||
| image_description = unidecode(img[0].get('alt', 'no description')) | ||
| image_link = img[0].get('src') | ||
| img[0].replaceWith(f' [Image: {image_description}] ') | ||
| summary = unidecode(str(bs.text)) | ||
| else: | ||
| summary = news['title'] | ||
| date_info = news['published_parsed'] if 'published' in news else news['updated_parsed'] | ||
| date_key = str("{}{}{}".format(date_info.tm_year, date_info.tm_mon, date_info.tm_mday)) | ||
| news_summary = { | ||
| 'Title': unidecode(news['title']), | ||
| 'Date': news['published'] if 'published' in news else news['updated'], | ||
| 'Link': news['link'], | ||
| 'Summary': summary, | ||
| 'Source of image': image_link, | ||
| 'Date key': date_key | ||
| } | ||
| return news_summary | ||
|
|
||
| def news_data_collection(self, parsed_url): | ||
| """Function that collects data from all news by calling make_news_data. | ||
| :return string of dictionaries | ||
| """ | ||
| all_information_about_news = parsed_url['entries'] | ||
| # amount_of_news = len(parsed_url.entries) | ||
| all_news = [] | ||
| self.logger.info('News gathering') | ||
| for news in all_information_about_news[:self.limit]: | ||
| try: # Exception when news is failed | ||
| dictionary_of_news_data = self.make_news_data(news) | ||
| except Exception as ex: | ||
| self.logger.error("Error processing news: {} {}".format(type(ex), ex)) | ||
| else: | ||
| all_news.append(dictionary_of_news_data) # make list of dictionaries of news data for optional output | ||
| return all_news | ||
|
|
||
| def get_news(self): | ||
| """Get news!""" | ||
| if self.date is None: | ||
| if self.url is None: | ||
| self.logger.error("URL is not provided.") | ||
| return | ||
| self.logger.info('Start parsing...') | ||
| try: | ||
| parsed_url = self.url_parsing() | ||
| about_website = self.information_about_site(parsed_url) | ||
| except Exception as ex: # for any exception after website parsing | ||
| self.logger.error("Error reading site data: {}, {}.".format(type(ex), ex)) | ||
| return | ||
| string_of_news_dictionaries = self.news_data_collection(parsed_url) | ||
| self.cache.caching(string_of_news_dictionaries, self.url) | ||
| else: | ||
| string_of_news_dictionaries = self.cache.returning(self.date, self.url)[:self.limit] | ||
| about_website = None | ||
| if not string_of_news_dictionaries: | ||
| self.logger.error('There is no news.') | ||
| return | ||
| file_name = None | ||
| if self.is_json: | ||
| converter = 'json' | ||
| elif self.pdf_file_name: | ||
| converter = 'pdf' | ||
| file_name = self.pdf_file_name | ||
| elif self.epub_file_name: | ||
| converter = 'epub' | ||
| file_name = self.epub_file_name | ||
| elif self.color: | ||
| converter = 'color' | ||
| else: | ||
| self.logger.info('Output news') | ||
| converter = 'text' | ||
| output = get_output_function(converter) | ||
| output(self.logger, string_of_news_dictionaries, about_website, file_name) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| class RSSReaderException(Exception): | ||
| pass |
Empty file.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.