Skip to content

Denis_Marfonov_marfonovdenis@gmail.com#32

Open
scarydzik wants to merge 31 commits into
epam-python-courses-7-bsu:masterfrom
scarydzik:master
Open

Denis_Marfonov_marfonovdenis@gmail.com#32
scarydzik wants to merge 31 commits into
epam-python-courses-7-bsu:masterfrom
scarydzik:master

Conversation

@scarydzik

Copy link
Copy Markdown

Iteration 4 without unittests and docstrings

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to use simple import in this case

return html


def _render_item(item):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

@HenadziStantchik HenadziStantchik Dec 3, 2019

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to avoid commented-out code in pushed commits.

Comment on lines +65 to +68
file = open(bookpath, "w", encoding="utf-8")
try:
file.write(text)
file.close()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually if you leave pass in the except block it is better to leave a comment why.

Comment on lines +13 to +30
class FeedError(Exception):
pass


class URLFormatError(FeedError):
pass


class FeedNotFoundError(FeedError):
pass


class IncorrectRSSError(FeedError):
pass


class LocalCacheError(FeedError):
pass

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to move your custom exceptions to the separate module

Comment on lines +6 to +19
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:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to be consistent with typehint usage: either typehint everywhere or nowhere.

import argparse
import logging
import time
import os.path

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import here

@@ -0,0 +1,110 @@
import time
import os.path
import html

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import here

@HenadziStantchik

Copy link
Copy Markdown
Collaborator

Here is feedback on your application:
Because you used from . in your imports, your app does not work if user will try to launch it using python rss_reader.py <rss url> ... (or something similar).
However, after package installation, your app still does not work (see Iteration 2 pic)
So in order to test your app I needed to change most of your imports.
Iteration 1:
After changing imports, does not work:
image
Iteration 2:
Installs nice, but does not work:
image

Iteration 3:
Unable to test.
Iteration 4:
Unable to test

Commits are informative and correspond to the recommended commit message style.
There are no tests.
Application is not in working condition, tested both on a clean machine and inside isolated docker container.
Overall code is readable, but has some issues specified in comments. It is however absolutely corresponds to the PEP8 guidelines.

@scarydzik

Copy link
Copy Markdown
Author

Because you used from . in your imports, your app does not work if user will try to launch it using python rss_reader.py ... (or something similar).

Program should be run with -m argument, as specified in the README:

$ python -m rss_reader ...

and from folder final_tast/rss_reader or from file __main__.py.
When I used absolute imports (import foo instead of from . import foo), console script from setup.py (rss-reader) didn't work.

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.
Also it mandatory to install dependencies manualy. 4th iteration required ebooklib, which is not mentioned in README (cause I forgot), but is mentioned in requirements.txt and setup.py.

If it's possible, can you please re-test the application?

@HenadziStantchik

Copy link
Copy Markdown
Collaborator

Ok, my bad not reading your README.md attentively.

Your app still does not completely work though:

image

After a bit of investigating, I figured that the problem is that you are trying to connect/create to the DB file that is situated (in my case) in final_task/rss_reader/data/ folder. The problem is that I do not have this folder at all, so it fails to open DB connection. However after creating data folder, everything works fine.

The same problem with your installed package

So here is feedback on your app:
Iteration 1:
--json contains html code, aside from that, everything is fine.
Iteration 2:
Installs fine, all iterations work the same as using python -m ....
Iteration 3:
Everything works fine.
Iteration 4:
Html conversion works fine.
Epub conversion works fine, but contain no images, only placeholders for them:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants