omdev 0.0.0.dev90__py3-none-any.whl → 0.0.0.dev91__py3-none-any.whl
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.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- omdev/__about__.py +5 -1
- omdev/prompttoolkit/__init__.py +11 -0
- omdev/prompttoolkit/apps/__init__.py +0 -0
- omdev/prompttoolkit/apps/ncdu.py +140 -0
- omdev/scripts/interp.py +27 -0
- omdev/scripts/pyproject.py +27 -0
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/METADATA +6 -3
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/RECORD +12 -9
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev90.dist-info → omdev-0.0.0.dev91.dist-info}/top_level.txt +0 -0
omdev/__about__.py
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ruff: noqa: F401
|
|
2
|
+
# flake8: noqa: F401
|
|
3
|
+
|
|
4
|
+
from prompt_toolkit import Application
|
|
5
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
6
|
+
from prompt_toolkit.key_binding import KeyPressEvent
|
|
7
|
+
from prompt_toolkit.layout import Layout
|
|
8
|
+
from prompt_toolkit.layout.containers import Window
|
|
9
|
+
from prompt_toolkit.styles import Style
|
|
10
|
+
from prompt_toolkit.widgets import Frame
|
|
11
|
+
from prompt_toolkit.widgets import TextArea
|
|
File without changes
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
2
|
+
import os
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
from omlish.lite.strings import format_num_bytes
|
|
6
|
+
|
|
7
|
+
from ... import prompttoolkit as ptk
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_directory_size(path: str) -> int:
|
|
11
|
+
total_size = 0
|
|
12
|
+
for dirpath, _, filenames in os.walk(path):
|
|
13
|
+
for f in filenames:
|
|
14
|
+
fp = os.path.join(dirpath, f)
|
|
15
|
+
try:
|
|
16
|
+
total_size += os.path.getsize(fp)
|
|
17
|
+
except OSError:
|
|
18
|
+
pass
|
|
19
|
+
return total_size
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dc.dataclass(frozen=True)
|
|
23
|
+
class Entry:
|
|
24
|
+
name: str
|
|
25
|
+
size: int
|
|
26
|
+
type: ta.Literal['dir', 'file']
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def scan_directory(path: str) -> list[Entry]:
|
|
30
|
+
entries: list[Entry] = []
|
|
31
|
+
|
|
32
|
+
with os.scandir(path) as it:
|
|
33
|
+
for entry in it:
|
|
34
|
+
if entry.is_dir(follow_symlinks=False):
|
|
35
|
+
size = get_directory_size(entry.path)
|
|
36
|
+
entries.append(Entry(entry.name + '/', size, 'dir'))
|
|
37
|
+
|
|
38
|
+
elif entry.is_file(follow_symlinks=False):
|
|
39
|
+
size = entry.stat().st_size
|
|
40
|
+
entries.append(Entry(entry.name, size, 'file'))
|
|
41
|
+
|
|
42
|
+
entries.sort(key=lambda x: x.size, reverse=True)
|
|
43
|
+
return entries
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class NcduApp:
|
|
47
|
+
def __init__(self, root_path: str) -> None:
|
|
48
|
+
super().__init__()
|
|
49
|
+
|
|
50
|
+
self._root_path = root_path
|
|
51
|
+
self._current_path = root_path
|
|
52
|
+
self._entries = scan_directory(root_path)
|
|
53
|
+
self._cursor = 0
|
|
54
|
+
|
|
55
|
+
self._text_area = ptk.TextArea(focusable=True)
|
|
56
|
+
self.update_display()
|
|
57
|
+
|
|
58
|
+
self._kb = ptk.KeyBindings()
|
|
59
|
+
self._kb.add('q')(self.exit_app)
|
|
60
|
+
for k in ['up', 'p']:
|
|
61
|
+
self._kb.add(k)(self.move_up)
|
|
62
|
+
for k in ['down', 'n']:
|
|
63
|
+
self._kb.add(k)(self.move_down)
|
|
64
|
+
self._kb.add('enter')(self.enter_directory)
|
|
65
|
+
self._kb.add('backspace')(self.go_back)
|
|
66
|
+
|
|
67
|
+
self._layout = ptk.Layout(ptk.Frame(self._text_area))
|
|
68
|
+
|
|
69
|
+
self._style = ptk.Style.from_dict({
|
|
70
|
+
'frame': 'bg:#008800 bold',
|
|
71
|
+
'text-area': 'bg:#000000 fg:#ffffff',
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
self._app: ptk.Application = ptk.Application(
|
|
75
|
+
layout=self._layout,
|
|
76
|
+
key_bindings=self._kb,
|
|
77
|
+
style=self._style,
|
|
78
|
+
full_screen=True,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
def update_display(self) -> None:
|
|
84
|
+
display_text = f'Current Directory: {self._current_path}\n\n'
|
|
85
|
+
for i, e in enumerate(self._entries):
|
|
86
|
+
indicator = '>' if i == self._cursor else ' '
|
|
87
|
+
display_text += f'{indicator} {e.name:<40} {format_num_bytes(e.size):>10}\n'
|
|
88
|
+
self._text_area.text = display_text
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
|
|
92
|
+
def move_up(self, event: ptk.KeyPressEvent) -> None:
|
|
93
|
+
if self._cursor > 0:
|
|
94
|
+
self._cursor -= 1
|
|
95
|
+
self.update_display()
|
|
96
|
+
|
|
97
|
+
def move_down(self, event: ptk.KeyPressEvent) -> None:
|
|
98
|
+
if self._cursor < len(self._entries) - 1:
|
|
99
|
+
self._cursor += 1
|
|
100
|
+
self.update_display()
|
|
101
|
+
|
|
102
|
+
def enter_directory(self, event: ptk.KeyPressEvent) -> None:
|
|
103
|
+
selected_entry = self._entries[self._cursor]
|
|
104
|
+
if selected_entry.type == 'dir':
|
|
105
|
+
self._current_path = os.path.join(self._current_path, selected_entry.name[:-1])
|
|
106
|
+
self._entries = scan_directory(self._current_path)
|
|
107
|
+
self._cursor = 0
|
|
108
|
+
self.update_display()
|
|
109
|
+
|
|
110
|
+
def go_back(self, event: ptk.KeyPressEvent) -> None:
|
|
111
|
+
if self._current_path != self._root_path:
|
|
112
|
+
self._current_path = os.path.dirname(self._current_path)
|
|
113
|
+
self._entries = scan_directory(self._current_path)
|
|
114
|
+
self._cursor = 0
|
|
115
|
+
self.update_display()
|
|
116
|
+
|
|
117
|
+
def exit_app(self, event: ptk.KeyPressEvent) -> None:
|
|
118
|
+
event.app.exit()
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
|
|
122
|
+
def run(self) -> None:
|
|
123
|
+
self._app.run()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _main() -> None:
|
|
127
|
+
import argparse
|
|
128
|
+
|
|
129
|
+
parser = argparse.ArgumentParser()
|
|
130
|
+
|
|
131
|
+
parser.add_argument('dir', default='.', nargs='?')
|
|
132
|
+
|
|
133
|
+
args = parser.parse_args()
|
|
134
|
+
|
|
135
|
+
ncdu_app = NcduApp(args.dir)
|
|
136
|
+
ncdu_app.run()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if __name__ == '__main__':
|
|
140
|
+
_main()
|
omdev/scripts/interp.py
CHANGED
|
@@ -626,6 +626,9 @@ def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
|
|
626
626
|
# ../../../omlish/lite/strings.py
|
|
627
627
|
|
|
628
628
|
|
|
629
|
+
##
|
|
630
|
+
|
|
631
|
+
|
|
629
632
|
def camel_case(name: str, lower: bool = False) -> str:
|
|
630
633
|
if not name:
|
|
631
634
|
return ''
|
|
@@ -640,6 +643,9 @@ def snake_case(name: str) -> str:
|
|
|
640
643
|
return '_'.join([name[l:r].lower() for l, r in zip([None, *uppers], [*uppers, None])]).strip('_')
|
|
641
644
|
|
|
642
645
|
|
|
646
|
+
##
|
|
647
|
+
|
|
648
|
+
|
|
643
649
|
def is_dunder(name: str) -> bool:
|
|
644
650
|
return (
|
|
645
651
|
name[:2] == name[-2:] == '__' and
|
|
@@ -658,10 +664,31 @@ def is_sunder(name: str) -> bool:
|
|
|
658
664
|
)
|
|
659
665
|
|
|
660
666
|
|
|
667
|
+
##
|
|
668
|
+
|
|
669
|
+
|
|
661
670
|
def attr_repr(obj: ta.Any, *attrs: str) -> str:
|
|
662
671
|
return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
|
663
672
|
|
|
664
673
|
|
|
674
|
+
##
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
FORMAT_NUM_BYTES_SUFFIXES: ta.Sequence[str] = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def format_num_bytes(num_bytes: int) -> str:
|
|
681
|
+
for i, suffix in enumerate(FORMAT_NUM_BYTES_SUFFIXES):
|
|
682
|
+
value = num_bytes / 1024 ** i
|
|
683
|
+
if num_bytes < 1024 ** (i + 1):
|
|
684
|
+
if value.is_integer():
|
|
685
|
+
return f'{int(value)}{suffix}'
|
|
686
|
+
else:
|
|
687
|
+
return f'{value:.2f}{suffix}'
|
|
688
|
+
|
|
689
|
+
return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
|
|
690
|
+
|
|
691
|
+
|
|
665
692
|
########################################
|
|
666
693
|
# ../../packaging/specifiers.py
|
|
667
694
|
# Copyright (c) Donald Stufft and individual contributors.
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -2014,6 +2014,9 @@ def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
|
|
2014
2014
|
# ../../../omlish/lite/strings.py
|
|
2015
2015
|
|
|
2016
2016
|
|
|
2017
|
+
##
|
|
2018
|
+
|
|
2019
|
+
|
|
2017
2020
|
def camel_case(name: str, lower: bool = False) -> str:
|
|
2018
2021
|
if not name:
|
|
2019
2022
|
return ''
|
|
@@ -2028,6 +2031,9 @@ def snake_case(name: str) -> str:
|
|
|
2028
2031
|
return '_'.join([name[l:r].lower() for l, r in zip([None, *uppers], [*uppers, None])]).strip('_')
|
|
2029
2032
|
|
|
2030
2033
|
|
|
2034
|
+
##
|
|
2035
|
+
|
|
2036
|
+
|
|
2031
2037
|
def is_dunder(name: str) -> bool:
|
|
2032
2038
|
return (
|
|
2033
2039
|
name[:2] == name[-2:] == '__' and
|
|
@@ -2046,10 +2052,31 @@ def is_sunder(name: str) -> bool:
|
|
|
2046
2052
|
)
|
|
2047
2053
|
|
|
2048
2054
|
|
|
2055
|
+
##
|
|
2056
|
+
|
|
2057
|
+
|
|
2049
2058
|
def attr_repr(obj: ta.Any, *attrs: str) -> str:
|
|
2050
2059
|
return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
|
2051
2060
|
|
|
2052
2061
|
|
|
2062
|
+
##
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
FORMAT_NUM_BYTES_SUFFIXES: ta.Sequence[str] = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
def format_num_bytes(num_bytes: int) -> str:
|
|
2069
|
+
for i, suffix in enumerate(FORMAT_NUM_BYTES_SUFFIXES):
|
|
2070
|
+
value = num_bytes / 1024 ** i
|
|
2071
|
+
if num_bytes < 1024 ** (i + 1):
|
|
2072
|
+
if value.is_integer():
|
|
2073
|
+
return f'{int(value)}{suffix}'
|
|
2074
|
+
else:
|
|
2075
|
+
return f'{value:.2f}{suffix}'
|
|
2076
|
+
|
|
2077
|
+
return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
|
|
2078
|
+
|
|
2079
|
+
|
|
2053
2080
|
########################################
|
|
2054
2081
|
# ../../packaging/specifiers.py
|
|
2055
2082
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev91
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -10,9 +10,9 @@ Classifier: Development Status :: 2 - Pre-Alpha
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
|
13
|
-
Requires-Python:
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: omlish ==0.0.0.
|
|
15
|
+
Requires-Dist: omlish ==0.0.0.dev91
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: black ~=24.10 ; extra == 'all'
|
|
18
18
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
@@ -21,6 +21,7 @@ Requires-Dist: pcpp ~=1.30 ; extra == 'all'
|
|
|
21
21
|
Requires-Dist: docutils ~=0.21 ; extra == 'all'
|
|
22
22
|
Requires-Dist: mypy ~=1.11 ; extra == 'all'
|
|
23
23
|
Requires-Dist: gprof2dot ~=2024.6 ; extra == 'all'
|
|
24
|
+
Requires-Dist: prompt-toolkit ~=3.0 ; extra == 'all'
|
|
24
25
|
Requires-Dist: tokenize-rt ~=6.1 ; extra == 'all'
|
|
25
26
|
Requires-Dist: wheel ~=0.44 ; extra == 'all'
|
|
26
27
|
Provides-Extra: black
|
|
@@ -35,6 +36,8 @@ Provides-Extra: mypy
|
|
|
35
36
|
Requires-Dist: mypy ~=1.11 ; extra == 'mypy'
|
|
36
37
|
Provides-Extra: prof
|
|
37
38
|
Requires-Dist: gprof2dot ~=2024.6 ; extra == 'prof'
|
|
39
|
+
Provides-Extra: prompttoolkit
|
|
40
|
+
Requires-Dist: prompt-toolkit ~=3.0 ; extra == 'prompttoolkit'
|
|
38
41
|
Provides-Extra: tokens
|
|
39
42
|
Requires-Dist: tokenize-rt ~=6.1 ; extra == 'tokens'
|
|
40
43
|
Provides-Extra: wheel
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
omdev/.manifests.json,sha256=juVlULcmZOz0t66Qf-GhpG_-4NGQU0XDmd7EjaRygxk,6257
|
|
2
|
-
omdev/__about__.py,sha256=
|
|
2
|
+
omdev/__about__.py,sha256=5MidJkdjpvZISIof4d7vMN7HhC7h5aUfl-FL0IpbY0A,1207
|
|
3
3
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
omdev/bracepy.py,sha256=I8EdqtDvxzAi3I8TuMEW-RBfwXfqKbwp06CfOdj3L1o,2743
|
|
5
5
|
omdev/classdot.py,sha256=YOvgy6x295I_8NKBbBlRVd3AN7Osirm_Lqt4Wj0j9rY,1631
|
|
@@ -98,6 +98,9 @@ omdev/precheck/lite.py,sha256=d8D-BY-Z0rqQigQ_aR9QXxdB3EBCHJc7WgBJngGiEiE,3871
|
|
|
98
98
|
omdev/precheck/main.py,sha256=2YizDZSDhMeQaZKVH83s99pBmtOUL9B-8dXwIcw6fQQ,2674
|
|
99
99
|
omdev/precheck/manifests.py,sha256=YfXqt6u0hlFXY0QkBMec6V_6Y9T4eCVAmrJDkQkB13U,774
|
|
100
100
|
omdev/precheck/scripts.py,sha256=qq6MXkxgrYngPg5pWnXH4uRSuRkP3mFqbeml1UmvGBc,1265
|
|
101
|
+
omdev/prompttoolkit/__init__.py,sha256=C4pFxNoIVo7cOH_jZ7-ruaYYd6DxEvuJr5ZGDrMFwXo,402
|
|
102
|
+
omdev/prompttoolkit/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
|
+
omdev/prompttoolkit/apps/ncdu.py,sha256=V2jZ-h3HN23KC5FB5gFjeMVZZbj-2j6zxyMca3O8OM0,3950
|
|
101
104
|
omdev/pyproject/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
102
105
|
omdev/pyproject/__main__.py,sha256=gn3Rl1aYPYdiTtEqa9ifi0t-e4ZwPY0vhJ4UXvYdJDY,165
|
|
103
106
|
omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
|
|
@@ -110,8 +113,8 @@ omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,
|
|
|
110
113
|
omdev/scripts/execrss.py,sha256=hJTWBig_-XqKIj1DphYTfeVDtdQTM1XUl-Hvzs2x9iY,451
|
|
111
114
|
omdev/scripts/exectime.py,sha256=dBdn3KV2jR6tCrzGvb9dTl2uGe2vNpLxmHMtExmnaiM,410
|
|
112
115
|
omdev/scripts/importtrace.py,sha256=Jbo3Yk2RAbE8_tJ97iTcVNpoxCJxrRb2tl1W_CV3NG0,14067
|
|
113
|
-
omdev/scripts/interp.py,sha256=
|
|
114
|
-
omdev/scripts/pyproject.py,sha256=
|
|
116
|
+
omdev/scripts/interp.py,sha256=ls04OE3g_TpiK5_inRfOzUvBGUtBgSt5vnkqC3eZhTM,72076
|
|
117
|
+
omdev/scripts/pyproject.py,sha256=g5f0AyRii_DSY-D6mMDUVqKNPNxWXAQJoWrYi1F2KGM,158772
|
|
115
118
|
omdev/scripts/slowcat.py,sha256=lssv4yrgJHiWfOiHkUut2p8E8Tq32zB-ujXESQxFFHY,2728
|
|
116
119
|
omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
117
120
|
omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
@@ -126,9 +129,9 @@ omdev/tools/piptools.py,sha256=-jR5q3w4sHqntxCLExFCBNIARB788FUsAbJ62PK2sBU,2774
|
|
|
126
129
|
omdev/tools/proftools.py,sha256=8ZU9x_Dq8eT2ZFwU9sJpDIvxcIn9qBc8y2ELKPb5e5M,1382
|
|
127
130
|
omdev/tools/rsttool.py,sha256=suwsfseUf8GH8rYmYygTUdif-Jk_bX1g9fYRLXaKkmM,1340
|
|
128
131
|
omdev/tools/sqlrepl.py,sha256=tmFZh80-xsGM62dyQ7_UGLebChrj7IHbIPYBWDJMgVk,5741
|
|
129
|
-
omdev-0.0.0.
|
|
130
|
-
omdev-0.0.0.
|
|
131
|
-
omdev-0.0.0.
|
|
132
|
-
omdev-0.0.0.
|
|
133
|
-
omdev-0.0.0.
|
|
134
|
-
omdev-0.0.0.
|
|
132
|
+
omdev-0.0.0.dev91.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
133
|
+
omdev-0.0.0.dev91.dist-info/METADATA,sha256=ETMAeQT2JIuqgfINKZYliLmHBYc5jW3pkOg09nSsmaY,1638
|
|
134
|
+
omdev-0.0.0.dev91.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
135
|
+
omdev-0.0.0.dev91.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
|
136
|
+
omdev-0.0.0.dev91.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
137
|
+
omdev-0.0.0.dev91.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|