Skip to content
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

Add stream filters #13

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/prawdditions/patch/ @RGood
/prawdditions/filters/ @PythonCoderAS
32 changes: 32 additions & 0 deletions docs/filters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
prawdditions.filters
====================

The prawdditions.filters contains one class, :class:`.Filterable`, and many
other helper classes & functions, that can be used with :class:`.Filterable`.

.. codeauthor:: PokestarFan <@PythonCoderAS>

The Filterable Class
--------------------

.. autoclass:: prawdditions.filters.filter.Filterable
:members:

Filter Callbacks
----------------

:class:`.Filterable` takes callback functions as filterable items, similar
to :func:`filter`. Custom functions can be provided, although there are a
lot of built-in functions that return callbacks.

.. toctree::
:maxdepth: 2
:caption: Filter Callbacks:

filters/base

Filter Capsules
---------------

.. autoclass:: prawdditions.filters.capsule.FilterCapsule
:members:
21 changes: 21 additions & 0 deletions docs/filters/base.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Base Callbacks
--------------

These are basic callback functions that most of the advanced callbacks
functions use to provide their functionality. These callbacks should not be
used, unless it is to filter an attribute of an unsupported model.

prawdditions.filters.base.filter_attribute
++++++++++++++++++++++++++++++++++++++++++

.. autofunction:: prawdditions.filters.base.filter_attribute

prawdditions.filters.base.filter_number
+++++++++++++++++++++++++++++++++++++++

.. autofunction:: prawdditions.filters.base.filter_number

prawdditions.filters.base.filter_true
+++++++++++++++++++++++++++++++++++++++

.. autofunction:: prawdditions.filters.base.filter_true
9 changes: 6 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@


PRAWdittions
PRAWdditions
============

PRAWdittions is a high-end library wrapper for PRAW that provides several
PRAWdditions is a high-end library wrapper for PRAW that provides several
functions that are missing from the main package. The only dependency is PRAW.

.. toctree::
:maxdepth: 2
:caption: Contents:
:caption: Table of Contents:

filters.rst
util.rst

patch.rst

Expand Down
5 changes: 5 additions & 0 deletions docs/util.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
prawdditions.util
-------------------------

.. automodule:: prawdditions.util
:members:
7 changes: 7 additions & 0 deletions prawdditions/filters/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Init file for the filter sub-module."""

from .capsule import FilterCapsule
from .filter import Filterable
from .redditor import *
from .subreddit import *
from .user_content import *
170 changes: 170 additions & 0 deletions prawdditions/filters/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
"""Base functions shared by all other filter modules."""
from typing import Union, Any, Callable, Type, Tuple
from praw.models import Comment, Redditor, Submission, Subreddit
from prawdditions.util import symbol_action


class BaseFilter:
"""Base Filters.

.. note:: This class should never be initialized directly. Instead,
call them from :class:`.Filterable`.
"""

@staticmethod
def filter_attribute(
check_class: Union[
Type[Union[Any, Comment, Redditor, Submission, Subreddit]],
Tuple[Type[Union[Any, Comment, Redditor, Submission, Subreddit]]],
],
classattr: str,
attribute: str,
value: [Union[Any, Comment, Redditor, Submission, Subreddit]],
) -> Callable[
[Union[Any, Comment, Redditor, Submission, Subreddit]], bool
]:
"""Filter by a specific attribute of a class.

:param check_class: The class to check for, such as
:class:`praw.models.Redditor` or :class`praw.models.Subreddit`.
:param classattr: The attribute to implement the base function for,
such as ``author`` for Redditor, ``subreddit`` for Subreddits, etc.
:param attribute: The attribute to check for.
:param value: The value that the attribute should equal.
:returns: A filter function for use in :meth:`.Filterable.filter`.

.. note:: This function is for equality. If you want to do numerical
comparisons, such as karma, use :meth:`.BaseFilter.filter_number`.
"""

def filter_func(
item: [Union[Any, Comment, Redditor, Submission, Subreddit]]
) -> bool:
"""Filter an item.

:param item: The item to check for equality
"""
return (
getattr(
(
item
if isinstance(item, check_class)
else getattr(item, classattr)
),
attribute,
)
== value
)

return filter_func

@classmethod
def filter_number(
cls,
check_class: Union[
Type[Union[Any, Comment, Redditor, Submission, Subreddit]],
Tuple[Type[Union[Any, Comment, Redditor, Submission, Subreddit]]],
],
classattr: str,
attribute: str,
symbol: str,
value: Union[Any, int],
) -> Callable[
[Union[Any, Comment, Redditor, Submission, Subreddit]], bool
]:
"""Filter by a numerical attribute of a class.

:param check_class: The class to check for, such as
:class:`praw.models.Redditor` or :class`praw.models.Subreddit`.
:param classattr: The attribute to implement the base function for,
such as ``author`` for Redditor, ``subreddit`` for Subreddits, etc.
:param attribute: The attribute to check for.
:param symbol: The comparison symbol. Currently supported symbols are
the Python comparison symbols ``<``, ``>``, ``<=``, ``>=``, ``==``,
and ``!=``.
:param value: The value that the attribute should compare to.
:raises: A :class:`ValueError` if the symbol given is invalid.
:returns: A filter function for use in :meth:`.Filterable.filter`.
"""
return symbol_action(
symbol,
lambda item: getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
< value,
lambda item: getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
> value,
lambda item: getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
<= value,
lambda item: getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
>= value,
cls.filter_attribute(classattr, attribute, value),
lambda item: getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
!= value,
)

@staticmethod
def filter_true(
check_class: Union[
Type[Union[Any, Comment, Redditor, Submission, Subreddit]],
Tuple[Type[Union[Any, Comment, Redditor, Submission, Subreddit]]],
],
classattr: str,
attribute: str,
opposite: bool = False,
) -> Callable[
[Union[Any, Comment, Redditor, Submission, Subreddit]], bool
]:
"""Filter by the boolean value of an attribute.

:param check_class: The class to check for, such as
:class:`praw.models.Redditor` or :class`praw.models.Subreddit`.
:param classattr: The attribute to implement the base function for,
such as ``author`` for Redditor, ``subreddit`` for Subreddits, etc.
:param attribute: The attribute to check for.
:param opposite: Whether to return items that matched False (
Default: False)
:returns: A filter function for use in :meth:`.Filterable.filter`.
"""

def filter_func(
item: [Union[Any, Comment, Redditor, Submission, Subreddit]]
) -> bool:
"""Filter an item.

:param item: The item to check for equality
"""
result = bool(
getattr(
item
if isinstance(item, check_class)
else getattr(item, classattr),
attribute,
)
)
return (not result) if opposite else result

return filter_func
Loading