refind


Namerefind JSON
Version 1.0.7 PyPI version JSON
download
home_pagehttps://github.com/Tails86/refind
SummaryA find clone in Python with both CLI and library interfaces
upload_time2023-10-07 03:47:29
maintainer
docs_urlNone
authorJames Smith
requires_python>=3.5
license
keywords find files regex print
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # refind

A find clone in Python with both CLI and library interfaces

## Shameless Promotion

Check out my other Python clone tools:
- [greplica](https://pypi.org/project/greplica/)
- [sedeuce](https://pypi.org/project/sedeuce/)

## Known Differences with find

- The Python module `re` is internally used for all regular expressions. The inputted regular
    expression is modified only when `sed` is selected as the regextype (default) in order to
    reverse meaning of escaped characters `+?|{}()`
- Parenthesis around expressions are not supported
- printf action differences
    - Birth time (B) is just treated the same as creation time (C)
    - %b, %k, %S, and %Y are not supported
    - Some formatting specifier inconsistencies may be encountered
- Not all options, tests, and actions are available (see help)
- pyprint actions are provided which uses Python string formatting

## Contribution

Feel free to open a bug report or make a merge request on [github](https://github.com/Tails86/refind/issues).

## Installation

This project is uploaded to PyPI at https://pypi.org/project/refind/

To install, ensure you are connected to the internet and execute: `python3 -m pip install refind --upgrade`

Once installed, there will be a script called `refind` under Python's script directory. Ensure Python's
scripts directory is under the environment variable `PATH` in order to be able to execute the script
properly from command line.

## CLI Help
```
Partially implements find command entirely in Python.

Usage: refind [path...] [expression...]

default path is the current directory (.); default action is -print

operators
    ! EXPR
    -not EXPR  Inverts the resulting value of the expression
    EXPR EXPR
    EXPR -a EXPR
    EXPR -and EXPR  Logically AND the left and right expressions' result
    EXPR -o EXPR
    EXPR -or EXPR   Logically OR the left and right expressions' result

normal options
    -help  Shows help and exit
    -maxdepth LEVELS  Sets the maximum directory depth of find (default: inf)
    -mindepth LEVELS  Sets the minimum directory depth of find (default: 0)
    -regextype TYPE  Set the regex type to py, sed, egrep (default: sed)
    --version  Shows version number and exits

tests
    -name PATTERN  Tests against the name of item using fnmatch
    -regex PATTERN  Tests against the path to the item using re
    -type [dfl]  Tests against item type directory, file, or link
    -path PATTERN
    -wholename PATTERN  Tests against the path to the item using fnmatch
    -amin [+-]N  Last accessed N, greater than +N, or less than -N minutes ago
    -anewer FILE  Last accessed time is more recent than given file
    -atime [+-]N  Last accessed N, greater than +N, or less than -N days ago
    -cmin [+-]N  Change N, greater than +N, or less than -N minutes ago
    -cnewer FILE  Change time is more recent than given file
    -ctime [+-]N  Change N, greater than +N, or less than -N days ago
    -empty  File is 0 bytes or directory empty
    -executable  Matches items which are executable by current user
    -false  Always false
    -gid GID  Matches with group ID
    -group GNAME  Matches with group name or ID
    -mmin [+-]N  Modified N, greater than +N, or less than -N minutes ago
    -newer FILE  Modified time is more recent than given file
    -mtime [+-]N  Modified N, greater than +N, or less than -N days ago
    -newerXY REF  Matches REF X < item Y where X and Y can be:
                  a: Accessed time of item or REF
                  c: Change time of item or REF
                  m: Modified time of item or REF
                  t: REF is timestamp (only valid for X)
    -nogroup  Matches items which aren't assigned to a group
    -nouser  Matches items which aren't assigned to a user
    -perm [-/]PERM  Matches exactly bits in PERM, all in -PERM, any in /PERM
    -readable  Matches items which are readable by current user
    -true  Always true
    -uid UID  Matches with user ID
    -user UNAME  Matches with user name or ID
    -writable  Matches items which are writable by current user

actions
    -print  Print the matching path
    -fprint FILE  Same as above but write to given FILE instead of stdout
    -print0  Print the matching path without newline
    -fprint0 FILE  Same as above but write to given FILE instead of stdout
    -printf FORMAT  Print using find printf formatting
    -fprintf FILE FORMAT  Same as above but write to given FILE instead of stdout
    -pyprint PYFORMAT  Print using python print() using named args:
                       find_root: the root given to refind
                       root: the directory name this item is in
                       rel_dir: the relative directory name from find_root
                       name: the name of the item
                       full_path: the full path of the item
                       mode_oct: st_mode as octal string
                       perm_oct: only the permissions part of mode_oct
                       perm: the permission in symbolic form
                       type: the type character
                       depth: the directory depth integer of this item
                       group: group name
                       user: user name
                       link: the file that this links to, if any
                       atime: access time as datetime
                       ctime: created time as datetime
                       mtime: modified time as datetime
                       any st args from os.stat()
    -fpyprint FILE PYFORMAT  Same as above but write to given FILE instead of stdout
    -pyprint0 PYFORMAT  Same as pyprint except end is set to empty string
    -fpyprint0 FILE PYFORMAT  Same as above but write to given FILE instead of stdout
    -exec COMMAND ;  Execute the COMMAND where {} in the command is the matching path
    -pyexec PYFORMAT ;  Execute the COMMAND as a pyformat (see pyprint)
    -delete  Deletes every matching path
```

## Library Help

refind can be used as a library from another module. The following is a simple example.
```py
    import refind
    from io import StringIO

    finder = refind.Finder()
    finder.set_min_depth(1)
    finder.add_root('.')
    finder.append_matcher(refind.TypeMatcher(FindType.FILE, FindType.DIRECTORY))
    output_stream = StringIO()
    finder.add_action(refind.PyPrintAction('{perm} {name}', file=output_stream))
    matches = finder.execute()

    # Prints the string that contains the result of all actions performed
    print(output_stream.getvalue(), end='')

    # Prints the contents of matches
    for match in matches:
        print(f'{match.find_root}, {match.root}, {match.rel_dir}, {match.name}, {match.full_path}')
```

The following Finder functions may be used to setup Finder.
```py
def add_root(self, *root_dirs:Union[str,List[str]]) -> None:
    '''
    Adds one or more roots. Each root will be treated as a glob when executing under Windows.
    '''

def set_min_depth(self, min_depth:int) -> None:
    '''
    Sets the global minimum depth limit
    '''

def set_max_depth(self, max_depth:int) -> None:
    '''
    Sets the global maximum depth limit
    '''

def add_action(self, action:Action) -> None:
    '''
    Adds an action that will be executed on matched paths.
    '''

def append_matcher(self, matcher:refind.Matcher, set_logic:refind.LogicOperation=None) -> None:
    '''
    Appends a matcher using a logic gate (AND or OR).
    Inputs: matcher - The matcher to append
            set_logic - The logic gate to use when appending this matcher
    '''

def set_matcher(self, matcher:refind.Matcher):
    '''
    Clears out the current matcher and sets the given matcher.
    '''
```

The following Actions are provided by refind.
```py
# Simply prints the full path of the item
PrintAction(end:str=None, file:io.IOBase=None, flush:bool=False)

# Prints the item using python format string
PyPrintAction(format:str, end:str=None, file:io.IOBase=None, flush:bool=False)

# Prints the item using printf format string
PrintfAction(format:str, end:str=None, file:io.IOBase=None, flush:bool=False)

# Executes custom command where {} is the full path to the item
ExecuteAction(command:List[str])

# Executes custom command where each element in the command is a format string
PyExecuteAction(command:List[str])

# Deletes the matched item
DeleteAction()
```

The following Matchers are provided by refind. Use set_invert() function after creating the
matcher if inverting the result is desired.
```py
# Statically return True or False for every item
StaticMatcher(value:bool)

# The default matcher when none specified (same as StaticMatcher(True))
DefaultMatcher()

# Matches against the name of the item
NameMatcher(pattern:str)

# Matches against the full path of the item
FullPathMatcher(pattern:str)

# Matches against the full path of the item using regex
RegexMatcher(pattern:str, regex_type:refind.RegexType)

# Matches against the item's type
TypeMatcher(*types:Union[refind.FindType,str,List[refind.FindType],List[str]])

# Matches against os.stat time relative to current time
StatTimeIncrementMatcher(
    value_comparison:refind.ValueComparison,
    rel_s:float,
    increment_s:float,
    current_time_s:float,
    stat_name:str
)

# Matches against os.stat time to an absolute time
StatTimeMatcher(
    value_comparison:refind.ValueComparison,
    stat_or_time:Union[os.stat_result,float],
    stat_name:str,
    r_stat_name:str=None
)

# Matches when directory empty or file size is 0 bytes
EmptyMatcher()

# Matches against access type for current user (read, write, execute)
AccessMatcher(access_type:int)

# Matches against group name or ID
GroupMatcher(gid_or_name:Union[int,str])

# Matches against user name or ID
UserMatcher(uid_or_name:Union[int,str])

# Matches against octal perm value
PermMatcher(perm:int, logic_operation:refind.LogicOperation=None)

# Gates two matchers together using logical AND or OR
GatedMatcher(
    left_matcher:refind.Matcher,
    right_matcher:refind.Matcher,
    operation:refind.LogicOperation=LogicOperation.AND
)
```

The Finder.execute() function should then be called once all options, actions, and matchers are
set on the Finder object.
```py
def execute(
        self,
        default_root:str=None,
        default_action:Action=None,
        return_list:bool=True
) -> Union[List[PathParser],None]:
    '''
    Inputs: default_root:  The default root to use when no root was previously added
            default_action:  The default action to use when no action was previously added.
            return_list:  set to False in order to save on memory when return not needed
    Returns: a list of PathParser when return_list is True or None when return_list is False
    '''
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Tails86/refind",
    "name": "refind",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.5",
    "maintainer_email": "",
    "keywords": "find,files,regex,print",
    "author": "James Smith",
    "author_email": "jmsmith86@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/5a/e3/f67b09e5f7a467efe4d9b3fb7620238e18acc20ea15594ce487078722771/refind-1.0.7.tar.gz",
    "platform": null,
    "description": "# refind\n\nA find clone in Python with both CLI and library interfaces\n\n## Shameless Promotion\n\nCheck out my other Python clone tools:\n- [greplica](https://pypi.org/project/greplica/)\n- [sedeuce](https://pypi.org/project/sedeuce/)\n\n## Known Differences with find\n\n- The Python module `re` is internally used for all regular expressions. The inputted regular\n    expression is modified only when `sed` is selected as the regextype (default) in order to\n    reverse meaning of escaped characters `+?|{}()`\n- Parenthesis around expressions are not supported\n- printf action differences\n    - Birth time (B) is just treated the same as creation time (C)\n    - %b, %k, %S, and %Y are not supported\n    - Some formatting specifier inconsistencies may be encountered\n- Not all options, tests, and actions are available (see help)\n- pyprint actions are provided which uses Python string formatting\n\n## Contribution\n\nFeel free to open a bug report or make a merge request on [github](https://github.com/Tails86/refind/issues).\n\n## Installation\n\nThis project is uploaded to PyPI at https://pypi.org/project/refind/\n\nTo install, ensure you are connected to the internet and execute: `python3 -m pip install refind --upgrade`\n\nOnce installed, there will be a script called `refind` under Python's script directory. Ensure Python's\nscripts directory is under the environment variable `PATH` in order to be able to execute the script\nproperly from command line.\n\n## CLI Help\n```\nPartially implements find command entirely in Python.\n\nUsage: refind [path...] [expression...]\n\ndefault path is the current directory (.); default action is -print\n\noperators\n    ! EXPR\n    -not EXPR  Inverts the resulting value of the expression\n    EXPR EXPR\n    EXPR -a EXPR\n    EXPR -and EXPR  Logically AND the left and right expressions' result\n    EXPR -o EXPR\n    EXPR -or EXPR   Logically OR the left and right expressions' result\n\nnormal options\n    -help  Shows help and exit\n    -maxdepth LEVELS  Sets the maximum directory depth of find (default: inf)\n    -mindepth LEVELS  Sets the minimum directory depth of find (default: 0)\n    -regextype TYPE  Set the regex type to py, sed, egrep (default: sed)\n    --version  Shows version number and exits\n\ntests\n    -name PATTERN  Tests against the name of item using fnmatch\n    -regex PATTERN  Tests against the path to the item using re\n    -type [dfl]  Tests against item type directory, file, or link\n    -path PATTERN\n    -wholename PATTERN  Tests against the path to the item using fnmatch\n    -amin [+-]N  Last accessed N, greater than +N, or less than -N minutes ago\n    -anewer FILE  Last accessed time is more recent than given file\n    -atime [+-]N  Last accessed N, greater than +N, or less than -N days ago\n    -cmin [+-]N  Change N, greater than +N, or less than -N minutes ago\n    -cnewer FILE  Change time is more recent than given file\n    -ctime [+-]N  Change N, greater than +N, or less than -N days ago\n    -empty  File is 0 bytes or directory empty\n    -executable  Matches items which are executable by current user\n    -false  Always false\n    -gid GID  Matches with group ID\n    -group GNAME  Matches with group name or ID\n    -mmin [+-]N  Modified N, greater than +N, or less than -N minutes ago\n    -newer FILE  Modified time is more recent than given file\n    -mtime [+-]N  Modified N, greater than +N, or less than -N days ago\n    -newerXY REF  Matches REF X < item Y where X and Y can be:\n                  a: Accessed time of item or REF\n                  c: Change time of item or REF\n                  m: Modified time of item or REF\n                  t: REF is timestamp (only valid for X)\n    -nogroup  Matches items which aren't assigned to a group\n    -nouser  Matches items which aren't assigned to a user\n    -perm [-/]PERM  Matches exactly bits in PERM, all in -PERM, any in /PERM\n    -readable  Matches items which are readable by current user\n    -true  Always true\n    -uid UID  Matches with user ID\n    -user UNAME  Matches with user name or ID\n    -writable  Matches items which are writable by current user\n\nactions\n    -print  Print the matching path\n    -fprint FILE  Same as above but write to given FILE instead of stdout\n    -print0  Print the matching path without newline\n    -fprint0 FILE  Same as above but write to given FILE instead of stdout\n    -printf FORMAT  Print using find printf formatting\n    -fprintf FILE FORMAT  Same as above but write to given FILE instead of stdout\n    -pyprint PYFORMAT  Print using python print() using named args:\n                       find_root: the root given to refind\n                       root: the directory name this item is in\n                       rel_dir: the relative directory name from find_root\n                       name: the name of the item\n                       full_path: the full path of the item\n                       mode_oct: st_mode as octal string\n                       perm_oct: only the permissions part of mode_oct\n                       perm: the permission in symbolic form\n                       type: the type character\n                       depth: the directory depth integer of this item\n                       group: group name\n                       user: user name\n                       link: the file that this links to, if any\n                       atime: access time as datetime\n                       ctime: created time as datetime\n                       mtime: modified time as datetime\n                       any st args from os.stat()\n    -fpyprint FILE PYFORMAT  Same as above but write to given FILE instead of stdout\n    -pyprint0 PYFORMAT  Same as pyprint except end is set to empty string\n    -fpyprint0 FILE PYFORMAT  Same as above but write to given FILE instead of stdout\n    -exec COMMAND ;  Execute the COMMAND where {} in the command is the matching path\n    -pyexec PYFORMAT ;  Execute the COMMAND as a pyformat (see pyprint)\n    -delete  Deletes every matching path\n```\n\n## Library Help\n\nrefind can be used as a library from another module. The following is a simple example.\n```py\n    import refind\n    from io import StringIO\n\n    finder = refind.Finder()\n    finder.set_min_depth(1)\n    finder.add_root('.')\n    finder.append_matcher(refind.TypeMatcher(FindType.FILE, FindType.DIRECTORY))\n    output_stream = StringIO()\n    finder.add_action(refind.PyPrintAction('{perm} {name}', file=output_stream))\n    matches = finder.execute()\n\n    # Prints the string that contains the result of all actions performed\n    print(output_stream.getvalue(), end='')\n\n    # Prints the contents of matches\n    for match in matches:\n        print(f'{match.find_root}, {match.root}, {match.rel_dir}, {match.name}, {match.full_path}')\n```\n\nThe following Finder functions may be used to setup Finder.\n```py\ndef add_root(self, *root_dirs:Union[str,List[str]]) -> None:\n    '''\n    Adds one or more roots. Each root will be treated as a glob when executing under Windows.\n    '''\n\ndef set_min_depth(self, min_depth:int) -> None:\n    '''\n    Sets the global minimum depth limit\n    '''\n\ndef set_max_depth(self, max_depth:int) -> None:\n    '''\n    Sets the global maximum depth limit\n    '''\n\ndef add_action(self, action:Action) -> None:\n    '''\n    Adds an action that will be executed on matched paths.\n    '''\n\ndef append_matcher(self, matcher:refind.Matcher, set_logic:refind.LogicOperation=None) -> None:\n    '''\n    Appends a matcher using a logic gate (AND or OR).\n    Inputs: matcher - The matcher to append\n            set_logic - The logic gate to use when appending this matcher\n    '''\n\ndef set_matcher(self, matcher:refind.Matcher):\n    '''\n    Clears out the current matcher and sets the given matcher.\n    '''\n```\n\nThe following Actions are provided by refind.\n```py\n# Simply prints the full path of the item\nPrintAction(end:str=None, file:io.IOBase=None, flush:bool=False)\n\n# Prints the item using python format string\nPyPrintAction(format:str, end:str=None, file:io.IOBase=None, flush:bool=False)\n\n# Prints the item using printf format string\nPrintfAction(format:str, end:str=None, file:io.IOBase=None, flush:bool=False)\n\n# Executes custom command where {} is the full path to the item\nExecuteAction(command:List[str])\n\n# Executes custom command where each element in the command is a format string\nPyExecuteAction(command:List[str])\n\n# Deletes the matched item\nDeleteAction()\n```\n\nThe following Matchers are provided by refind. Use set_invert() function after creating the\nmatcher if inverting the result is desired.\n```py\n# Statically return True or False for every item\nStaticMatcher(value:bool)\n\n# The default matcher when none specified (same as StaticMatcher(True))\nDefaultMatcher()\n\n# Matches against the name of the item\nNameMatcher(pattern:str)\n\n# Matches against the full path of the item\nFullPathMatcher(pattern:str)\n\n# Matches against the full path of the item using regex\nRegexMatcher(pattern:str, regex_type:refind.RegexType)\n\n# Matches against the item's type\nTypeMatcher(*types:Union[refind.FindType,str,List[refind.FindType],List[str]])\n\n# Matches against os.stat time relative to current time\nStatTimeIncrementMatcher(\n    value_comparison:refind.ValueComparison,\n    rel_s:float,\n    increment_s:float,\n    current_time_s:float,\n    stat_name:str\n)\n\n# Matches against os.stat time to an absolute time\nStatTimeMatcher(\n    value_comparison:refind.ValueComparison,\n    stat_or_time:Union[os.stat_result,float],\n    stat_name:str,\n    r_stat_name:str=None\n)\n\n# Matches when directory empty or file size is 0 bytes\nEmptyMatcher()\n\n# Matches against access type for current user (read, write, execute)\nAccessMatcher(access_type:int)\n\n# Matches against group name or ID\nGroupMatcher(gid_or_name:Union[int,str])\n\n# Matches against user name or ID\nUserMatcher(uid_or_name:Union[int,str])\n\n# Matches against octal perm value\nPermMatcher(perm:int, logic_operation:refind.LogicOperation=None)\n\n# Gates two matchers together using logical AND or OR\nGatedMatcher(\n    left_matcher:refind.Matcher,\n    right_matcher:refind.Matcher,\n    operation:refind.LogicOperation=LogicOperation.AND\n)\n```\n\nThe Finder.execute() function should then be called once all options, actions, and matchers are\nset on the Finder object.\n```py\ndef execute(\n        self,\n        default_root:str=None,\n        default_action:Action=None,\n        return_list:bool=True\n) -> Union[List[PathParser],None]:\n    '''\n    Inputs: default_root:  The default root to use when no root was previously added\n            default_action:  The default action to use when no action was previously added.\n            return_list:  set to False in order to save on memory when return not needed\n    Returns: a list of PathParser when return_list is True or None when return_list is False\n    '''\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A find clone in Python with both CLI and library interfaces",
    "version": "1.0.7",
    "project_urls": {
        "Bug Reports": "https://github.com/Tails86/refind/issues",
        "Documentation": "https://github.com/Tails86/refind",
        "Homepage": "https://github.com/Tails86/refind",
        "Source Code": "https://github.com/Tails86/refind"
    },
    "split_keywords": [
        "find",
        "files",
        "regex",
        "print"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c2661fb63a36a495bd4f4ff4e63ca5bab90580103dbe4d57843a91b441a546a9",
                "md5": "0dc36b6a793607a710f32b43a28b2106",
                "sha256": "edabd2d637e8c25ce9094e6dd9f1c5729221c7d8e22c4acb650302e10d05be3f"
            },
            "downloads": -1,
            "filename": "refind-1.0.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0dc36b6a793607a710f32b43a28b2106",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.5",
            "size": 20536,
            "upload_time": "2023-10-07T03:47:27",
            "upload_time_iso_8601": "2023-10-07T03:47:27.834813Z",
            "url": "https://files.pythonhosted.org/packages/c2/66/1fb63a36a495bd4f4ff4e63ca5bab90580103dbe4d57843a91b441a546a9/refind-1.0.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5ae3f67b09e5f7a467efe4d9b3fb7620238e18acc20ea15594ce487078722771",
                "md5": "fa9c55ee088d11d1c441b09e177eb576",
                "sha256": "faea3416d920dd60b4f6c046b408ba7a4165ae873ea0de22de6b31592156ec7a"
            },
            "downloads": -1,
            "filename": "refind-1.0.7.tar.gz",
            "has_sig": false,
            "md5_digest": "fa9c55ee088d11d1c441b09e177eb576",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.5",
            "size": 21810,
            "upload_time": "2023-10-07T03:47:29",
            "upload_time_iso_8601": "2023-10-07T03:47:29.399461Z",
            "url": "https://files.pythonhosted.org/packages/5a/e3/f67b09e5f7a467efe4d9b3fb7620238e18acc20ea15594ce487078722771/refind-1.0.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-07 03:47:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Tails86",
    "github_project": "refind",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "refind"
}
        
Elapsed time: 0.12517s