Denis_Marfonov_marfonovdenis@gmail.com#32
Conversation
Created CLI using argparse and handle all arguments from the first iteration.
Created Feed class for parsed RSS. For now, it only stores necessary fields from object returned by feedparser library.
Created module with function for parsing html, which can be in "description" field of RSS item.
Added methods for generating json and plain text with links list to Feed class
Added logging with ERROR level to display handled custom exceptions; and INFO level to display verbose status messages if corresponding argument is provided.
This is done in order to add main() function to 'console scripts' in setup.py
Added __init__ to make correct python package. Created __main__ to allow starting package as program Added content to setup.py.
If db is not exist or invalid, it is (re-)created. Feed class become context manager, it no longer contains heavy methods in init. Also, it helps to close db connector properly. Finally, slightly change plain text conversion.
| @@ -0,0 +1,3 @@ | |||
| from .rss_reader import main | |||
There was a problem hiding this comment.
It is better to use simple import in this case
| return html | ||
|
|
||
|
|
||
| def _render_item(item): |
There was a problem hiding this comment.
Here and below: Usually underscore should be used either inside classes for method names or for variables that override nuilt-in names. You do not actually need to use it every time.
| html.append(title) | ||
| html.append("</h1>") | ||
|
|
||
| for i in items: |
There was a problem hiding this comment.
Here and below, it is better to avoid one letter variable names. No matter how simple statement is.
|
|
||
|
|
||
| def _create_html(book_id, bookpath, text): | ||
| # text = html.escape(text) |
There was a problem hiding this comment.
It is better to avoid commented-out code in pushed commits.
| file = open(bookpath, "w", encoding="utf-8") | ||
| try: | ||
| file.write(text) | ||
| file.close() |
There was a problem hiding this comment.
It is better to use context manager for this instead of manually opening-closing file descriptor.
| file.write(text) | ||
| file.close() | ||
| except (AttributeError, OSError): | ||
| pass |
There was a problem hiding this comment.
Usually if you leave pass in the except block it is better to leave a comment why.
| class FeedError(Exception): | ||
| pass | ||
|
|
||
|
|
||
| class URLFormatError(FeedError): | ||
| pass | ||
|
|
||
|
|
||
| class FeedNotFoundError(FeedError): | ||
| pass | ||
|
|
||
|
|
||
| class IncorrectRSSError(FeedError): | ||
| pass | ||
|
|
||
|
|
||
| class LocalCacheError(FeedError): | ||
| pass |
There was a problem hiding this comment.
It is better to move your custom exceptions to the separate module
| def __len__(self) -> int: | ||
| return len(self.items_dict) | ||
|
|
||
| def __contains__(self, __x: object) -> bool: | ||
| return __x in self.items_dict | ||
|
|
||
| def __iter__(self): | ||
| return self.items_dict.__iter__() | ||
|
|
||
| def __init__(self, initial=None): | ||
| self.items_dict = dict() | ||
| self._next_index_ = 1 | ||
|
|
||
| if initial is not None: |
There was a problem hiding this comment.
It is better to be consistent with typehint usage: either typehint everywhere or nowhere.
| import argparse | ||
| import logging | ||
| import time | ||
| import os.path |
There was a problem hiding this comment.
Unused import here
| @@ -0,0 +1,110 @@ | |||
| import time | |||
| import os.path | |||
| import html | |||
There was a problem hiding this comment.
Unused import here
Program should be run with -m argument, as specified in the README: and from folder As for the installation from PyPi, iteration 3 has version 0.3.post1 (because i accidently uploaded incompleted project as 0.3); iteration 4 was not added to TestPyPi, because I finished it just before deadline and forgot about it. Now I've added 4th iteration to TestPyPi. If it's possible, can you please re-test the application? |




Iteration 4 without unittests and docstrings