pseek 2.1.5__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pseek-2.2.0/PKG-INFO +95 -0
- pseek-2.2.0/README.md +81 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek/cli.py +19 -4
- pseek-2.2.0/pseek/parser.py +187 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek/searcher.py +65 -71
- pseek-2.2.0/pseek/utils.py +12 -0
- pseek-2.2.0/pseek.egg-info/PKG-INFO +95 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek.egg-info/SOURCES.txt +3 -1
- {pseek-2.1.5 → pseek-2.2.0}/pseek.egg-info/requires.txt +1 -0
- pseek-2.2.0/pyproject.toml +23 -0
- pseek-2.1.5/PKG-INFO +0 -105
- pseek-2.1.5/README.md +0 -80
- pseek-2.1.5/pseek.egg-info/PKG-INFO +0 -105
- pseek-2.1.5/setup.py +0 -24
- {pseek-2.1.5 → pseek-2.2.0}/LICENSE +0 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek/__init__.py +0 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek.egg-info/dependency_links.txt +0 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek.egg-info/entry_points.txt +0 -0
- {pseek-2.1.5 → pseek-2.2.0}/pseek.egg-info/top_level.txt +0 -0
- {pseek-2.1.5 → pseek-2.2.0}/setup.cfg +0 -0
pseek-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pseek
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: Pseek is a Python library to search files, folders, and text
|
|
5
|
+
Author-email: Arian <ariannasiri86@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ArianN8610/pysearch
|
|
8
|
+
Requires-Python: >=3.6
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: click==8.1.8
|
|
12
|
+
Requires-Dist: lark==1.2.2
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Pseek
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
* **Search in file & folder names**
|
|
24
|
+
* **Search inside file contents**
|
|
25
|
+
* **Highlight matches** in terminal output
|
|
26
|
+
* **Optimized for speed** with ThreadPoolExecutor
|
|
27
|
+
* **Cross-platform** (Linux, macOS, Windows)
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### **1️⃣ Install via `pip` (Recommended)**
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pip install pseek
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### **2️⃣ Install from source**
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
git clone https://github.com/ArianN8610/pysearch.git
|
|
41
|
+
cd pseek
|
|
42
|
+
pip install click==8.1.8
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Run the command with a search query:
|
|
48
|
+
```sh
|
|
49
|
+
pseek <query> [options]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Search for a keyword in file & folder names
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
pseek "my_keyword" --path /path/to/search --file --directory
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Search inside file contents
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
pseek "error" --path /var/logs --content
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Search only in specific file types
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
pseek "TODO" --path ./projects --ext py --ext txt
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Search by regex
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
pseek "error\d+" --regex
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Command Options
|
|
79
|
+
|
|
80
|
+
| Option | Description |
|
|
81
|
+
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
82
|
+
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
83
|
+
| `--file` | Search only in file names |
|
|
84
|
+
| `--directory` | Search only in directory names |
|
|
85
|
+
| `--content` | Search inside file contents |
|
|
86
|
+
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
87
|
+
| `--case-sensitive` | Make the search case-sensitive (except when --expr is enabled, in which case you can make it case sensitive by putting c before term: c"foo") |
|
|
88
|
+
| `--regex` | Use regular expressions to search (except when --expr is enabled, in which case you can make it regex by putting r before term: r"foo") |
|
|
89
|
+
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
90
|
+
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
91
|
+
| `--word` | Match the whole word only (except when --expr is enabled, in which case you can make it match whole word by putting w before term: w"foo") |
|
|
92
|
+
| `--expr` | Enable to write conditions in the query. Example: r"foo.*bar" and ("bar" or "baz") and not "qux" (To use regex, word, and case-sensitive features, you can use the prefixes r, w, and c before terms. Allowed modes: r, w, c, wc, cw, rc, cr. Examples: r"foo.*bar", wc"Foo", cr".*Foo", ...) |
|
|
93
|
+
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
94
|
+
| `--full-path` | Display full path of files and directories |
|
|
95
|
+
| `--no-content` | Only display files path for content search |
|
pseek-2.2.0/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Pseek
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* **Search in file & folder names**
|
|
10
|
+
* **Search inside file contents**
|
|
11
|
+
* **Highlight matches** in terminal output
|
|
12
|
+
* **Optimized for speed** with ThreadPoolExecutor
|
|
13
|
+
* **Cross-platform** (Linux, macOS, Windows)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### **1️⃣ Install via `pip` (Recommended)**
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
pip install pseek
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### **2️⃣ Install from source**
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
git clone https://github.com/ArianN8610/pysearch.git
|
|
27
|
+
cd pseek
|
|
28
|
+
pip install click==8.1.8
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
Run the command with a search query:
|
|
34
|
+
```sh
|
|
35
|
+
pseek <query> [options]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Search for a keyword in file & folder names
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
pseek "my_keyword" --path /path/to/search --file --directory
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Search inside file contents
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
pseek "error" --path /var/logs --content
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Search only in specific file types
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
pseek "TODO" --path ./projects --ext py --ext txt
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Search by regex
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
pseek "error\d+" --regex
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Command Options
|
|
65
|
+
|
|
66
|
+
| Option | Description |
|
|
67
|
+
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
68
|
+
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
69
|
+
| `--file` | Search only in file names |
|
|
70
|
+
| `--directory` | Search only in directory names |
|
|
71
|
+
| `--content` | Search inside file contents |
|
|
72
|
+
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
73
|
+
| `--case-sensitive` | Make the search case-sensitive (except when --expr is enabled, in which case you can make it case sensitive by putting c before term: c"foo") |
|
|
74
|
+
| `--regex` | Use regular expressions to search (except when --expr is enabled, in which case you can make it regex by putting r before term: r"foo") |
|
|
75
|
+
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
76
|
+
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
77
|
+
| `--word` | Match the whole word only (except when --expr is enabled, in which case you can make it match whole word by putting w before term: w"foo") |
|
|
78
|
+
| `--expr` | Enable to write conditions in the query. Example: r"foo.*bar" and ("bar" or "baz") and not "qux" (To use regex, word, and case-sensitive features, you can use the prefixes r, w, and c before terms. Allowed modes: r, w, c, wc, cw, rc, cr. Examples: r"foo.*bar", wc"Foo", cr".*Foo", ...) |
|
|
79
|
+
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
80
|
+
| `--full-path` | Display full path of files and directories |
|
|
81
|
+
| `--no-content` | Only display files path for content search |
|
|
@@ -11,9 +11,23 @@ from .searcher import Search
|
|
|
11
11
|
@click.option('-d', '--directory', is_flag=True, help='Search only in directory names.')
|
|
12
12
|
@click.option('-c', '--content', is_flag=True, help='Search inside file contents.')
|
|
13
13
|
# Additional options
|
|
14
|
-
@click.option('-C', '--case-sensitive', is_flag=True,
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
@click.option('-C', '--case-sensitive', is_flag=True,
|
|
15
|
+
help='Make the search case-sensitive '
|
|
16
|
+
'(except when --expr is enabled, '
|
|
17
|
+
'in which case you can make it case sensitive by putting c before term: c"foo")')
|
|
18
|
+
@click.option('-r', '--regex', is_flag=True,
|
|
19
|
+
help='Use regular expressions to search '
|
|
20
|
+
'(except when --expr is enabled, '
|
|
21
|
+
'in which case you can make it regex by putting r before term: r"foo")')
|
|
22
|
+
@click.option('-w', '--word', is_flag=True,
|
|
23
|
+
help='Match whole words only '
|
|
24
|
+
'(except when --expr is enabled, '
|
|
25
|
+
'in which case you can make it match whole word by putting w before term: w"foo")')
|
|
26
|
+
@click.option('--expr', is_flag=True,
|
|
27
|
+
help='Enable to write conditions in the query. Example: r"foo.*bar" and ("bar" or "baz") and not "qux" '
|
|
28
|
+
'(To use regex, word, and case-sensitive features, '
|
|
29
|
+
'you can use the prefixes r, w, and c before terms. Allowed modes: r, w, c, wc, cw, rc, cr. '
|
|
30
|
+
'Examples: r"foo.*bar", wc"Foo", cr".*Foo", ...)')
|
|
17
31
|
# Extension filters
|
|
18
32
|
@click.option('--ext', multiple=True, type=click.STRING,
|
|
19
33
|
help='Include files with these extensions. Example: --ext py --ext js')
|
|
@@ -35,7 +49,7 @@ from .searcher import Search
|
|
|
35
49
|
@click.option('--full-path', is_flag=True, help='Display full paths for results.')
|
|
36
50
|
@click.option('--no-content', is_flag=True, help='Only display files path for content search.')
|
|
37
51
|
def search(query, path, file, directory, content, case_sensitive, ext, exclude_ext, regex, include, exclude,
|
|
38
|
-
re_include, re_exclude, word, max_size, min_size, full_path, no_content):
|
|
52
|
+
re_include, re_exclude, word, expr, max_size, min_size, full_path, no_content):
|
|
39
53
|
"""Search for files, directories, and file content based on the query."""
|
|
40
54
|
# If no search type is specified, search in all types.
|
|
41
55
|
if not any((file, directory, content)):
|
|
@@ -54,6 +68,7 @@ def search(query, path, file, directory, content, case_sensitive, ext, exclude_e
|
|
|
54
68
|
re_include=re_include,
|
|
55
69
|
re_exclude=re_exclude,
|
|
56
70
|
whole_word=word,
|
|
71
|
+
expr=expr,
|
|
57
72
|
max_size=max_size,
|
|
58
73
|
min_size=min_size,
|
|
59
74
|
full_path=full_path,
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
import click
|
|
4
|
+
from lark import Lark, Transformer
|
|
5
|
+
from .utils import compile_regex
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ExprNode:
|
|
9
|
+
"""Base class for expression tree nodes"""
|
|
10
|
+
def evaluate(self, text: str) -> bool:
|
|
11
|
+
raise NotImplementedError
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TermNode(ExprNode):
|
|
15
|
+
"""Node representing a single search term"""
|
|
16
|
+
def __init__(self, term: str, regex, whole_word, case_sensitive):
|
|
17
|
+
self.raw_term = term
|
|
18
|
+
self.whole_word = whole_word
|
|
19
|
+
self.case_sensitive = case_sensitive
|
|
20
|
+
|
|
21
|
+
flags = 0 if case_sensitive else re.IGNORECASE # Adjust case sensitivity
|
|
22
|
+
|
|
23
|
+
# Build the regex pattern
|
|
24
|
+
if not regex:
|
|
25
|
+
term = re.escape(term) # Escape if not regex
|
|
26
|
+
# Apply whole-word matching only if not using regex (or if desired behavior is defined)
|
|
27
|
+
if whole_word:
|
|
28
|
+
term = r'\b' + term + r'\b'
|
|
29
|
+
|
|
30
|
+
self.pattern = compile_regex(term, flags) # Precompile the regex pattern for performance
|
|
31
|
+
|
|
32
|
+
def evaluate(self, text: str) -> bool:
|
|
33
|
+
return bool(self.pattern.search(text))
|
|
34
|
+
|
|
35
|
+
def count_matches(self, text: str) -> int:
|
|
36
|
+
"""Count how many times the pattern appears in the text"""
|
|
37
|
+
return len(list(self.pattern.finditer(text)))
|
|
38
|
+
|
|
39
|
+
def get_binary_pattern(self) -> re.Pattern:
|
|
40
|
+
"""Return a compiled binary regex pattern"""
|
|
41
|
+
return re.compile(self.pattern.pattern.encode("utf-8"), self.pattern.flags)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class NotNode(ExprNode):
|
|
45
|
+
"""Node representing logical NOT"""
|
|
46
|
+
def __init__(self, child: ExprNode):
|
|
47
|
+
self.child = child
|
|
48
|
+
|
|
49
|
+
def evaluate(self, text: str) -> bool:
|
|
50
|
+
return not self.child.evaluate(text)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AndNode(ExprNode):
|
|
54
|
+
"""Node representing logical AND"""
|
|
55
|
+
def __init__(self, left: ExprNode, right: ExprNode):
|
|
56
|
+
self.left = left
|
|
57
|
+
self.right = right
|
|
58
|
+
|
|
59
|
+
def evaluate(self, text: str) -> bool:
|
|
60
|
+
return self.left.evaluate(text) and self.right.evaluate(text)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class OrNode(ExprNode):
|
|
64
|
+
"""Node representing logical OR"""
|
|
65
|
+
def __init__(self, left: ExprNode, right: ExprNode):
|
|
66
|
+
self.left = left
|
|
67
|
+
self.right = right
|
|
68
|
+
|
|
69
|
+
def evaluate(self, text: str) -> bool:
|
|
70
|
+
return self.left.evaluate(text) or self.right.evaluate(text)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Lark grammar for parsing logical expressions
|
|
74
|
+
query_grammar = r"""
|
|
75
|
+
?start: expr
|
|
76
|
+
|
|
77
|
+
?expr: or_expr
|
|
78
|
+
|
|
79
|
+
?or_expr: and_expr
|
|
80
|
+
| or_expr "or" and_expr -> or_expr
|
|
81
|
+
|
|
82
|
+
?and_expr: not_expr
|
|
83
|
+
| and_expr "and" not_expr -> and_expr
|
|
84
|
+
|
|
85
|
+
?not_expr: "not" not_expr -> not_expr
|
|
86
|
+
| term
|
|
87
|
+
|
|
88
|
+
?term: PREFIXED_STRING -> prefixed_string
|
|
89
|
+
| ESCAPED_STRING -> string
|
|
90
|
+
| "(" expr ")"
|
|
91
|
+
|
|
92
|
+
PREFIXED_STRING: /(r|c|w|rc|cr|cw|wc)"([^"\\]|\\.)*"/
|
|
93
|
+
|
|
94
|
+
%import common.ESCAPED_STRING
|
|
95
|
+
%import common.WS
|
|
96
|
+
%ignore WS
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class TreeToExpr(Transformer):
|
|
101
|
+
"""Transform parsed tree into expression tree (ExprNode subclasses)"""
|
|
102
|
+
def __init__(self):
|
|
103
|
+
super().__init__()
|
|
104
|
+
|
|
105
|
+
def string(self, s):
|
|
106
|
+
""" Match normal quoted string: "foo" """
|
|
107
|
+
term = s[0][1:-1] # Remove surrounding quotes (e.g., "foo" -> foo)
|
|
108
|
+
return TermNode(
|
|
109
|
+
term,
|
|
110
|
+
False,
|
|
111
|
+
False,
|
|
112
|
+
False
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def prefixed_string(self, s):
|
|
116
|
+
text = str(s[0]) # e.g., 'rc"pattern"'
|
|
117
|
+
prefix = text.split('"', 1)[0].lower()
|
|
118
|
+
content = text.split('"', 1)[1][:-1]
|
|
119
|
+
|
|
120
|
+
return TermNode(
|
|
121
|
+
content,
|
|
122
|
+
regex='r' in prefix,
|
|
123
|
+
whole_word='w' in prefix,
|
|
124
|
+
case_sensitive='c' in prefix,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def and_expr(self, args):
|
|
128
|
+
return AndNode(args[0], args[1])
|
|
129
|
+
|
|
130
|
+
def or_expr(self, args):
|
|
131
|
+
return OrNode(args[0], args[1])
|
|
132
|
+
|
|
133
|
+
def not_expr(self, args):
|
|
134
|
+
return NotNode(args[0])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def parse_query_expression(query: str, expr, regex, whole_word, case_sensitive) -> ExprNode:
|
|
138
|
+
"""
|
|
139
|
+
Function to parse the query and return expression tree.
|
|
140
|
+
If expr is False, treat the whole query as a single term.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
if not expr:
|
|
144
|
+
return TermNode(query, regex, whole_word, case_sensitive)
|
|
145
|
+
|
|
146
|
+
# Otherwise, parse using Lark
|
|
147
|
+
parser = Lark(query_grammar, parser="lalr")
|
|
148
|
+
try:
|
|
149
|
+
tree = parser.parse(query)
|
|
150
|
+
return TreeToExpr().transform(tree)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
click.echo(click.style("Query parser error:\n\n", fg='red') + str(e))
|
|
153
|
+
sys.exit(1)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def highlight_text_safe(expr: ExprNode, text: str) -> str:
|
|
157
|
+
matches = []
|
|
158
|
+
|
|
159
|
+
def collect_matches(node):
|
|
160
|
+
if isinstance(node, TermNode):
|
|
161
|
+
for match in node.pattern.finditer(text):
|
|
162
|
+
matches.append((match.start(), match.end()))
|
|
163
|
+
elif isinstance(node, (AndNode, OrNode)):
|
|
164
|
+
collect_matches(node.left)
|
|
165
|
+
collect_matches(node.right)
|
|
166
|
+
elif isinstance(node, NotNode):
|
|
167
|
+
collect_matches(node.child)
|
|
168
|
+
|
|
169
|
+
collect_matches(expr)
|
|
170
|
+
|
|
171
|
+
# Remove overlaps (for example, if one match was inside another match)
|
|
172
|
+
matches.sort() # sort by start position
|
|
173
|
+
merged = []
|
|
174
|
+
for start, end in matches:
|
|
175
|
+
if not merged or start >= merged[-1][1]: # no overlap
|
|
176
|
+
merged.append((start, end))
|
|
177
|
+
|
|
178
|
+
# Create the final text with highlight
|
|
179
|
+
result = []
|
|
180
|
+
last = 0
|
|
181
|
+
for start, end in merged:
|
|
182
|
+
result.append(text[last:start])
|
|
183
|
+
result.append(click.style(text[start:end], fg='green'))
|
|
184
|
+
last = end
|
|
185
|
+
result.append(text[last:])
|
|
186
|
+
|
|
187
|
+
return ''.join(result)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import sys
|
|
3
|
-
import click
|
|
4
1
|
import mmap
|
|
2
|
+
import click
|
|
5
3
|
from pathlib import Path
|
|
4
|
+
from .utils import compile_regex
|
|
5
|
+
from .parser import parse_query_expression, TermNode, highlight_text_safe
|
|
6
6
|
from concurrent.futures import ThreadPoolExecutor
|
|
7
7
|
|
|
8
8
|
# Extensions that are not suitable for content search (binary, media, etc.)
|
|
@@ -19,18 +19,9 @@ EXCLUDED_EXTENSIONS = {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def compile_regex(txt, flags=0):
|
|
23
|
-
if txt is not None:
|
|
24
|
-
try:
|
|
25
|
-
return re.compile(txt, flags)
|
|
26
|
-
except re.error as e:
|
|
27
|
-
click.echo(click.style(f"Regex compile error: {e}", fg='red'))
|
|
28
|
-
sys.exit(1)
|
|
29
|
-
|
|
30
|
-
|
|
31
22
|
class Search:
|
|
32
23
|
def __init__(self, base_path, query, case_sensitive, ext, exclude_ext, regex, include, exclude, re_include,
|
|
33
|
-
re_exclude, whole_word, max_size, min_size, full_path, no_content):
|
|
24
|
+
re_exclude, whole_word, expr, max_size, min_size, full_path, no_content):
|
|
34
25
|
"""Initialize search parameters"""
|
|
35
26
|
self.base_path = Path(base_path)
|
|
36
27
|
self.query = query
|
|
@@ -38,11 +29,12 @@ class Search:
|
|
|
38
29
|
self.ext = set(ext)
|
|
39
30
|
self.exclude_ext = set(exclude_ext)
|
|
40
31
|
self.regex = regex
|
|
41
|
-
self.include = {Path(p) for p in include}
|
|
42
|
-
self.exclude = {Path(p) for p in exclude}
|
|
32
|
+
self.include = {Path(p).resolve() for p in include}
|
|
33
|
+
self.exclude = {Path(p).resolve() for p in exclude}
|
|
43
34
|
self.re_include = re_include
|
|
44
35
|
self.re_exclude = re_exclude
|
|
45
36
|
self.whole_word = whole_word
|
|
37
|
+
self.expr = expr
|
|
46
38
|
self.max_size = max_size
|
|
47
39
|
self.min_size = min_size
|
|
48
40
|
self.full_path = full_path
|
|
@@ -83,18 +75,7 @@ class Search:
|
|
|
83
75
|
|
|
84
76
|
def search(self, search_type: str):
|
|
85
77
|
"""Main search function. search_type can be 'file', 'directory' or 'content'"""
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
# Prepare query: escape if not regex
|
|
89
|
-
if not self.regex:
|
|
90
|
-
query = re.escape(query)
|
|
91
|
-
|
|
92
|
-
# Apply whole-word matching only if not using regex (or if desired behavior is defined)
|
|
93
|
-
if self.whole_word and not self.regex:
|
|
94
|
-
query = rf'\b{query}\b'
|
|
95
|
-
|
|
96
|
-
flags = 0 if self.case_sensitive else re.IGNORECASE # Adjust case sensitivity
|
|
97
|
-
pattern = compile_regex(query, flags) # Precompile the regex pattern for performance
|
|
78
|
+
pattern = parse_query_expression(self.query, self.expr, self.regex, self.whole_word, self.case_sensitive)
|
|
98
79
|
|
|
99
80
|
if search_type in ('file', 'directory'):
|
|
100
81
|
matches = []
|
|
@@ -104,19 +85,25 @@ class Search:
|
|
|
104
85
|
except Exception:
|
|
105
86
|
continue
|
|
106
87
|
# Skip if conditions fail or if name doesn't match the query
|
|
107
|
-
if self.should_skip(p_resolved, search_type) or not pattern.
|
|
88
|
+
if self.should_skip(p_resolved, search_type) or not pattern.evaluate(p.name):
|
|
108
89
|
continue
|
|
109
90
|
|
|
110
91
|
# Highlight matched query in the name
|
|
111
|
-
highlighted_name = pattern
|
|
92
|
+
highlighted_name = highlight_text_safe(pattern, p.name)
|
|
112
93
|
# Choose parent path based on full_path flag
|
|
113
94
|
p_parent = p_resolved.parent if self.full_path else p.parent
|
|
114
95
|
matches.append(f'{p_parent}\\{highlighted_name}')
|
|
115
96
|
else: # content search
|
|
116
97
|
# Use dictionary: key: file path (colored), value: list of line matches
|
|
117
98
|
matches = {} if not self.no_content else set()
|
|
118
|
-
|
|
119
|
-
|
|
99
|
+
|
|
100
|
+
# If expression is simple and is a single TermNode, we can use binary pattern
|
|
101
|
+
binary_pattern = None
|
|
102
|
+
if isinstance(pattern, TermNode):
|
|
103
|
+
try:
|
|
104
|
+
binary_pattern = pattern.get_binary_pattern()
|
|
105
|
+
except Exception:
|
|
106
|
+
binary_pattern = None
|
|
120
107
|
|
|
121
108
|
def process_file(file_path: Path):
|
|
122
109
|
"""Process a single file for content search"""
|
|
@@ -129,48 +116,55 @@ class Search:
|
|
|
129
116
|
with open(file_path, 'rb') as f:
|
|
130
117
|
# Memory-map the file for efficient access
|
|
131
118
|
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
119
|
+
if binary_pattern is not None:
|
|
120
|
+
if not binary_pattern.search(mm):
|
|
121
|
+
return
|
|
122
|
+
else:
|
|
123
|
+
# fallback: decode whole file for complex expressions
|
|
124
|
+
try:
|
|
125
|
+
content = mm.read().decode('utf-8')
|
|
126
|
+
except UnicodeDecodeError:
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
if not pattern.evaluate(content):
|
|
140
130
|
return
|
|
141
131
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
132
|
+
# Choose the file path format based on the full_path setting
|
|
133
|
+
file_label = str(file_path.resolve()) if self.full_path else str(file_path)
|
|
134
|
+
|
|
135
|
+
# Avoid searching through the entire file content if the fast-content flag is True
|
|
136
|
+
if self.no_content:
|
|
137
|
+
matches.add(click.style(file_label, fg='cyan'))
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
lines = []
|
|
141
|
+
mm.seek(0) # Move the cursor to the beginning of the file
|
|
142
|
+
|
|
143
|
+
# Iterate over each line in the file
|
|
144
|
+
for num, line in enumerate(iter(mm.readline, b''), 1):
|
|
145
|
+
try:
|
|
146
|
+
# Decode the binary line as UTF-8 and strip whitespace
|
|
147
|
+
line_decoded = line.decode('utf-8').strip()
|
|
148
|
+
except UnicodeDecodeError:
|
|
149
|
+
# Skip lines that can't be decoded
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
# If the pattern matches in the decoded line
|
|
153
|
+
if pattern.evaluate(line_decoded):
|
|
154
|
+
count = pattern.count_matches(line_decoded) if isinstance(pattern, TermNode) else 0
|
|
155
|
+
# Highlight the matching parts in green
|
|
156
|
+
highlighted = highlight_text_safe(pattern, line_decoded)
|
|
157
|
+
# Show a note if the pattern repeats 3 or more times
|
|
158
|
+
count_query = f' - Repeated {count} times' if count >= 3 else ''
|
|
159
|
+
# Format the output line with line number and highlighted matches
|
|
160
|
+
lines.append(
|
|
161
|
+
click.style(f'Line {num}{count_query}: ', fg='magenta') + highlighted
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# If any matching lines were found
|
|
165
|
+
if lines:
|
|
166
|
+
# Add the file and its matching lines to the results
|
|
167
|
+
matches[click.style(file_label, fg='cyan')] = lines
|
|
174
168
|
except Exception:
|
|
175
169
|
return
|
|
176
170
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pseek
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: Pseek is a Python library to search files, folders, and text
|
|
5
|
+
Author-email: Arian <ariannasiri86@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ArianN8610/pysearch
|
|
8
|
+
Requires-Python: >=3.6
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: click==8.1.8
|
|
12
|
+
Requires-Dist: lark==1.2.2
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Pseek
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
* **Search in file & folder names**
|
|
24
|
+
* **Search inside file contents**
|
|
25
|
+
* **Highlight matches** in terminal output
|
|
26
|
+
* **Optimized for speed** with ThreadPoolExecutor
|
|
27
|
+
* **Cross-platform** (Linux, macOS, Windows)
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### **1️⃣ Install via `pip` (Recommended)**
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pip install pseek
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### **2️⃣ Install from source**
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
git clone https://github.com/ArianN8610/pysearch.git
|
|
41
|
+
cd pseek
|
|
42
|
+
pip install click==8.1.8
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Run the command with a search query:
|
|
48
|
+
```sh
|
|
49
|
+
pseek <query> [options]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Search for a keyword in file & folder names
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
pseek "my_keyword" --path /path/to/search --file --directory
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Search inside file contents
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
pseek "error" --path /var/logs --content
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Search only in specific file types
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
pseek "TODO" --path ./projects --ext py --ext txt
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Search by regex
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
pseek "error\d+" --regex
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Command Options
|
|
79
|
+
|
|
80
|
+
| Option | Description |
|
|
81
|
+
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
82
|
+
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
83
|
+
| `--file` | Search only in file names |
|
|
84
|
+
| `--directory` | Search only in directory names |
|
|
85
|
+
| `--content` | Search inside file contents |
|
|
86
|
+
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
87
|
+
| `--case-sensitive` | Make the search case-sensitive (except when --expr is enabled, in which case you can make it case sensitive by putting c before term: c"foo") |
|
|
88
|
+
| `--regex` | Use regular expressions to search (except when --expr is enabled, in which case you can make it regex by putting r before term: r"foo") |
|
|
89
|
+
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
90
|
+
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
91
|
+
| `--word` | Match the whole word only (except when --expr is enabled, in which case you can make it match whole word by putting w before term: w"foo") |
|
|
92
|
+
| `--expr` | Enable to write conditions in the query. Example: r"foo.*bar" and ("bar" or "baz") and not "qux" (To use regex, word, and case-sensitive features, you can use the prefixes r, w, and c before terms. Allowed modes: r, w, c, wc, cw, rc, cr. Examples: r"foo.*bar", wc"Foo", cr".*Foo", ...) |
|
|
93
|
+
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
94
|
+
| `--full-path` | Display full path of files and directories |
|
|
95
|
+
| `--no-content` | Only display files path for content search |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pseek"
|
|
7
|
+
version = "2.2.0"
|
|
8
|
+
description = "Pseek is a Python library to search files, folders, and text"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Arian", email = "ariannasiri86@gmail.com"}
|
|
14
|
+
]
|
|
15
|
+
requires-python = ">=3.6"
|
|
16
|
+
dependencies = [
|
|
17
|
+
"click==8.1.8",
|
|
18
|
+
"lark==1.2.2"
|
|
19
|
+
]
|
|
20
|
+
urls = {Homepage = "https://github.com/ArianN8610/pysearch"}
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
pseek = "pseek.cli:search"
|
pseek-2.1.5/PKG-INFO
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pseek
|
|
3
|
-
Version: 2.1.5
|
|
4
|
-
Summary: Pseek is a Python library to search files, folders, and text
|
|
5
|
-
Home-page: https://github.com/ArianN8610/pysearch
|
|
6
|
-
Author: Arian
|
|
7
|
-
Author-email: ariannasiri86@gmail.com
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Requires-Dist: click==8.1.8
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: author-email
|
|
17
|
-
Dynamic: classifier
|
|
18
|
-
Dynamic: description
|
|
19
|
-
Dynamic: description-content-type
|
|
20
|
-
Dynamic: home-page
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
Dynamic: requires-dist
|
|
23
|
-
Dynamic: requires-python
|
|
24
|
-
Dynamic: summary
|
|
25
|
-
|
|
26
|
-
# Pseek
|
|
27
|
-
|
|
28
|
-
## Overview
|
|
29
|
-
|
|
30
|
-
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
31
|
-
|
|
32
|
-
## Features
|
|
33
|
-
|
|
34
|
-
* **Search in file & folder names**
|
|
35
|
-
* **Search inside file contents**
|
|
36
|
-
* **Highlight matches** in terminal output
|
|
37
|
-
* **Optimized for speed** with ThreadPoolExecutor
|
|
38
|
-
* **Cross-platform** (Linux, macOS, Windows)
|
|
39
|
-
|
|
40
|
-
## Installation
|
|
41
|
-
|
|
42
|
-
### **1️⃣ Install via `pip` (Recommended)**
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
pip install pseek
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### **2️⃣ Install from source**
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
git clone https://github.com/ArianN8610/pysearch.git
|
|
52
|
-
cd pseek
|
|
53
|
-
pip install click==8.1.8
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Usage
|
|
57
|
-
|
|
58
|
-
Run the command with a search query:
|
|
59
|
-
```sh
|
|
60
|
-
pseek <query> [options]
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Examples
|
|
64
|
-
|
|
65
|
-
### Search for a keyword in file & folder names
|
|
66
|
-
|
|
67
|
-
```sh
|
|
68
|
-
pseek "my_keyword" --path /path/to/search --file --directory
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Search inside file contents
|
|
72
|
-
|
|
73
|
-
```sh
|
|
74
|
-
pseek "error" --path /var/logs --content
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Search only in specific file types
|
|
78
|
-
|
|
79
|
-
```sh
|
|
80
|
-
pseek "TODO" --path ./projects --ext py --ext txt
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Search by regex
|
|
84
|
-
|
|
85
|
-
```sh
|
|
86
|
-
pseek "error\d+" --regex
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Command Options
|
|
90
|
-
|
|
91
|
-
| Option | Description |
|
|
92
|
-
|--------------------------------|------------------------------------------------------------------|
|
|
93
|
-
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
94
|
-
| `--file` | Search only in file names |
|
|
95
|
-
| `--directory` | Search only in directory names |
|
|
96
|
-
| `--content` | Search inside file contents |
|
|
97
|
-
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
98
|
-
| `--case-sensitive` | Make the search case-sensitive |
|
|
99
|
-
| `--regex` | Use regular expression for searching |
|
|
100
|
-
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
101
|
-
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
102
|
-
| `--word` | Match the whole word only |
|
|
103
|
-
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
104
|
-
| `--full-path` | Display full path of files and directories |
|
|
105
|
-
| `--no-content` | Only display files path for content search |
|
pseek-2.1.5/README.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Pseek
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
* **Search in file & folder names**
|
|
10
|
-
* **Search inside file contents**
|
|
11
|
-
* **Highlight matches** in terminal output
|
|
12
|
-
* **Optimized for speed** with ThreadPoolExecutor
|
|
13
|
-
* **Cross-platform** (Linux, macOS, Windows)
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
### **1️⃣ Install via `pip` (Recommended)**
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
pip install pseek
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### **2️⃣ Install from source**
|
|
24
|
-
|
|
25
|
-
```sh
|
|
26
|
-
git clone https://github.com/ArianN8610/pysearch.git
|
|
27
|
-
cd pseek
|
|
28
|
-
pip install click==8.1.8
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
Run the command with a search query:
|
|
34
|
-
```sh
|
|
35
|
-
pseek <query> [options]
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Examples
|
|
39
|
-
|
|
40
|
-
### Search for a keyword in file & folder names
|
|
41
|
-
|
|
42
|
-
```sh
|
|
43
|
-
pseek "my_keyword" --path /path/to/search --file --directory
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Search inside file contents
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
pseek "error" --path /var/logs --content
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Search only in specific file types
|
|
53
|
-
|
|
54
|
-
```sh
|
|
55
|
-
pseek "TODO" --path ./projects --ext py --ext txt
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Search by regex
|
|
59
|
-
|
|
60
|
-
```sh
|
|
61
|
-
pseek "error\d+" --regex
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Command Options
|
|
65
|
-
|
|
66
|
-
| Option | Description |
|
|
67
|
-
|--------------------------------|------------------------------------------------------------------|
|
|
68
|
-
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
69
|
-
| `--file` | Search only in file names |
|
|
70
|
-
| `--directory` | Search only in directory names |
|
|
71
|
-
| `--content` | Search inside file contents |
|
|
72
|
-
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
73
|
-
| `--case-sensitive` | Make the search case-sensitive |
|
|
74
|
-
| `--regex` | Use regular expression for searching |
|
|
75
|
-
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
76
|
-
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
77
|
-
| `--word` | Match the whole word only |
|
|
78
|
-
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
79
|
-
| `--full-path` | Display full path of files and directories |
|
|
80
|
-
| `--no-content` | Only display files path for content search |
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pseek
|
|
3
|
-
Version: 2.1.5
|
|
4
|
-
Summary: Pseek is a Python library to search files, folders, and text
|
|
5
|
-
Home-page: https://github.com/ArianN8610/pysearch
|
|
6
|
-
Author: Arian
|
|
7
|
-
Author-email: ariannasiri86@gmail.com
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Requires-Dist: click==8.1.8
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: author-email
|
|
17
|
-
Dynamic: classifier
|
|
18
|
-
Dynamic: description
|
|
19
|
-
Dynamic: description-content-type
|
|
20
|
-
Dynamic: home-page
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
Dynamic: requires-dist
|
|
23
|
-
Dynamic: requires-python
|
|
24
|
-
Dynamic: summary
|
|
25
|
-
|
|
26
|
-
# Pseek
|
|
27
|
-
|
|
28
|
-
## Overview
|
|
29
|
-
|
|
30
|
-
A powerful command-line tool for searching files, directories, and content inside files efficiently. The tool supports searching by name, content, extensions, and more with advanced filtering options.
|
|
31
|
-
|
|
32
|
-
## Features
|
|
33
|
-
|
|
34
|
-
* **Search in file & folder names**
|
|
35
|
-
* **Search inside file contents**
|
|
36
|
-
* **Highlight matches** in terminal output
|
|
37
|
-
* **Optimized for speed** with ThreadPoolExecutor
|
|
38
|
-
* **Cross-platform** (Linux, macOS, Windows)
|
|
39
|
-
|
|
40
|
-
## Installation
|
|
41
|
-
|
|
42
|
-
### **1️⃣ Install via `pip` (Recommended)**
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
pip install pseek
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### **2️⃣ Install from source**
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
git clone https://github.com/ArianN8610/pysearch.git
|
|
52
|
-
cd pseek
|
|
53
|
-
pip install click==8.1.8
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Usage
|
|
57
|
-
|
|
58
|
-
Run the command with a search query:
|
|
59
|
-
```sh
|
|
60
|
-
pseek <query> [options]
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Examples
|
|
64
|
-
|
|
65
|
-
### Search for a keyword in file & folder names
|
|
66
|
-
|
|
67
|
-
```sh
|
|
68
|
-
pseek "my_keyword" --path /path/to/search --file --directory
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Search inside file contents
|
|
72
|
-
|
|
73
|
-
```sh
|
|
74
|
-
pseek "error" --path /var/logs --content
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Search only in specific file types
|
|
78
|
-
|
|
79
|
-
```sh
|
|
80
|
-
pseek "TODO" --path ./projects --ext py --ext txt
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Search by regex
|
|
84
|
-
|
|
85
|
-
```sh
|
|
86
|
-
pseek "error\d+" --regex
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Command Options
|
|
90
|
-
|
|
91
|
-
| Option | Description |
|
|
92
|
-
|--------------------------------|------------------------------------------------------------------|
|
|
93
|
-
| `--path` | Base directory to search in (default: current directory `.`) |
|
|
94
|
-
| `--file` | Search only in file names |
|
|
95
|
-
| `--directory` | Search only in directory names |
|
|
96
|
-
| `--content` | Search inside file contents |
|
|
97
|
-
| `--ext`, `--exclude-ext` | Filter by file extension (e.g., `.txt`, `.log`) |
|
|
98
|
-
| `--case-sensitive` | Make the search case-sensitive |
|
|
99
|
-
| `--regex` | Use regular expression for searching |
|
|
100
|
-
| `--include`, `--exclude` | Limit search results to specific set of directories or files |
|
|
101
|
-
| `--re-include`, `--re-exclude` | Limit search results to specific directories or files with regex |
|
|
102
|
-
| `--word` | Match the whole word only |
|
|
103
|
-
| `--max-size`, `--min-size` | Specify maximum and minimum sizes for files and directories |
|
|
104
|
-
| `--full-path` | Display full path of files and directories |
|
|
105
|
-
| `--no-content` | Only display files path for content search |
|
pseek-2.1.5/setup.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
|
|
3
|
-
with open("README.md", encoding="utf-8") as f:
|
|
4
|
-
long_description = f.read()
|
|
5
|
-
|
|
6
|
-
setup(
|
|
7
|
-
name="pseek",
|
|
8
|
-
version="2.1.5",
|
|
9
|
-
author="Arian",
|
|
10
|
-
author_email="ariannasiri86@gmail.com",
|
|
11
|
-
description="Pseek is a Python library to search files, folders, and text",
|
|
12
|
-
long_description=long_description,
|
|
13
|
-
long_description_content_type="text/markdown",
|
|
14
|
-
url="https://github.com/ArianN8610/pysearch",
|
|
15
|
-
packages=find_packages(),
|
|
16
|
-
classifiers=[
|
|
17
|
-
"Programming Language :: Python :: 3",
|
|
18
|
-
"License :: OSI Approved :: MIT License",
|
|
19
|
-
"Operating System :: OS Independent",
|
|
20
|
-
],
|
|
21
|
-
python_requires=">=3.6",
|
|
22
|
-
install_requires=["click==8.1.8"],
|
|
23
|
-
entry_points={"console_scripts": ["pseek=pseek.cli:search"]}
|
|
24
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|