onlyone 2.4.3__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.
Files changed (50) hide show
  1. onlyone-2.4.3/LICENSE +21 -0
  2. onlyone-2.4.3/PKG-INFO +160 -0
  3. onlyone-2.4.3/README.md +130 -0
  4. onlyone-2.4.3/pyproject.toml +49 -0
  5. onlyone-2.4.3/setup.cfg +4 -0
  6. onlyone-2.4.3/src/onlyone/__init__.py +43 -0
  7. onlyone-2.4.3/src/onlyone/cli.py +483 -0
  8. onlyone-2.4.3/src/onlyone/commands.py +92 -0
  9. onlyone-2.4.3/src/onlyone/core/__init__.py +38 -0
  10. onlyone-2.4.3/src/onlyone/core/deduplicator.py +124 -0
  11. onlyone-2.4.3/src/onlyone/core/grouper.py +77 -0
  12. onlyone-2.4.3/src/onlyone/core/hasher.py +87 -0
  13. onlyone-2.4.3/src/onlyone/core/interfaces.py +205 -0
  14. onlyone-2.4.3/src/onlyone/core/models.py +329 -0
  15. onlyone-2.4.3/src/onlyone/core/scanner.py +252 -0
  16. onlyone-2.4.3/src/onlyone/core/sorter.py +45 -0
  17. onlyone-2.4.3/src/onlyone/core/stages.py +272 -0
  18. onlyone-2.4.3/src/onlyone/gui/__init__.py +9 -0
  19. onlyone-2.4.3/src/onlyone/gui/custom_widgets/__init__.py +13 -0
  20. onlyone-2.4.3/src/onlyone/gui/custom_widgets/duplicate_groups_list.py +113 -0
  21. onlyone-2.4.3/src/onlyone/gui/custom_widgets/favourite_dirs_dialog.py +89 -0
  22. onlyone-2.4.3/src/onlyone/gui/custom_widgets/image_preview_label.py +97 -0
  23. onlyone-2.4.3/src/onlyone/gui/launcher.py +16 -0
  24. onlyone-2.4.3/src/onlyone/gui/main_window.py +411 -0
  25. onlyone-2.4.3/src/onlyone/gui/main_window_ui.py +225 -0
  26. onlyone-2.4.3/src/onlyone/gui/worker.py +74 -0
  27. onlyone-2.4.3/src/onlyone/services/__init__.py +6 -0
  28. onlyone-2.4.3/src/onlyone/services/duplicate_service.py +77 -0
  29. onlyone-2.4.3/src/onlyone/services/file_service.py +96 -0
  30. onlyone-2.4.3/src/onlyone/utils/__init__.py +7 -0
  31. onlyone-2.4.3/src/onlyone/utils/convert_utils.py +78 -0
  32. onlyone-2.4.3/src/onlyone.egg-info/PKG-INFO +160 -0
  33. onlyone-2.4.3/src/onlyone.egg-info/SOURCES.txt +48 -0
  34. onlyone-2.4.3/src/onlyone.egg-info/dependency_links.txt +1 -0
  35. onlyone-2.4.3/src/onlyone.egg-info/entry_points.txt +3 -0
  36. onlyone-2.4.3/src/onlyone.egg-info/requires.txt +11 -0
  37. onlyone-2.4.3/src/onlyone.egg-info/top_level.txt +1 -0
  38. onlyone-2.4.3/tests/test_argument_parsing.py +244 -0
  39. onlyone-2.4.3/tests/test_cli.py +405 -0
  40. onlyone-2.4.3/tests/test_commands.py +166 -0
  41. onlyone-2.4.3/tests/test_convert_utils.py +109 -0
  42. onlyone-2.4.3/tests/test_critical_edge_cases.py +359 -0
  43. onlyone-2.4.3/tests/test_deduplicator.py +423 -0
  44. onlyone-2.4.3/tests/test_duplicate_service.py +213 -0
  45. onlyone-2.4.3/tests/test_file_service.py +269 -0
  46. onlyone-2.4.3/tests/test_grouper.py +120 -0
  47. onlyone-2.4.3/tests/test_hasher.py +154 -0
  48. onlyone-2.4.3/tests/test_scanner.py +312 -0
  49. onlyone-2.4.3/tests/test_stages.py +315 -0
  50. onlyone-2.4.3/tests/test_worker.py +223 -0
onlyone-2.4.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 initumX (initum.x@gmail.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
onlyone-2.4.3/PKG-INFO ADDED
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: onlyone
3
+ Version: 2.4.3
4
+ Summary: Fast duplicate file finder with optional GUI
5
+ Author-email: initumX <initum.x@gmail.com>
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Environment :: X11 Applications :: Qt
9
+ Classifier: Intended Audience :: End Users/Desktop
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: xxhash>=3.0.0
21
+ Requires-Dist: send2trash>=1.8.0
22
+ Provides-Extra: gui
23
+ Requires-Dist: PySide6; extra == "gui"
24
+ Requires-Dist: Pillow>=9.0.0; extra == "gui"
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0; extra == "dev"
27
+ Requires-Dist: pytest-qt>=4.0; extra == "dev"
28
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+
32
+ # [OnlyOne](https://initumx.github.io/onlyone/)
33
+
34
+ ![screenshot](/deduplicator224.png "Main Window")
35
+
36
+ A PyQt-based tool for finding and removing duplicate files with advanced filtering and progress tracking.
37
+
38
+ *Note: GUI-version is "extra"(not mandatory part), so to install app with gui, use:
39
+
40
+ `pip install onlyone[gui]`
41
+
42
+ ### How to install and run
43
+ ### First Way - use venv (virtual environment)
44
+ 1. Create python virtual environment and go there:
45
+ python3 venv ~/onlyone && cd ~/onlyone
46
+ -----
47
+ 2. Activate it:
48
+ source ~/onlyone/bin/activate
49
+ -----
50
+ 3.Install onlyone into it:
51
+ pip install onlyone[gui]
52
+ -----
53
+ Done.
54
+ Now you can run `onlyone` or `onlyone-gui` commands from your virtual environment
55
+
56
+ ### Second Way - wait for build release :)
57
+
58
+ ### Features
59
+ Filters files by file size and extension
60
+ -------
61
+ Sorts files inside duplicate groups by path depth and filename length
62
+ ------
63
+ Supports deduplication modes: fast, normal, full
64
+ ------
65
+ Preview images directly in the interface (in gui-version)
66
+ ------
67
+ Progress tracking both for searching duplicates and deleting them (in gui-version)
68
+ -------
69
+ Statistics/report
70
+ ------
71
+ Context menu (open, reveal in explorer and delete file(s) options)
72
+ ------
73
+ One click deletion (delete all duplicates at once)
74
+ ------
75
+ Manage priority directories
76
+
77
+ ### How does it work?
78
+ 1. Recursively scans folder using filters (min/max size, extension)
79
+ 2. Apply the cheapest check first (compare by size)
80
+ 3. Further checking depends on mode:
81
+ a) "fast": checks hash-sum of first 64+ KB of files (false positives very possible)
82
+ b) "normal": checks hash-sum of 3 parts of the file: front -> middle -> end (generally reliable)
83
+ c) "full": checks hash-sum of front -> middle -> entire file (very slow for large files)
84
+ 4. Shows the list of groups sorted in descending order (groups with larger files come first).
85
+ --------
86
+ Files inside a group are sorted by path/filename length (you can regulate this).
87
+
88
+ ### Deleting all duplicates at once
89
+ The main principle: ALL files moved to trash EXCEPT the FIRST file in each group.
90
+ ---
91
+ Which file is "first" depends on sorting:
92
+ Priority files(files from "Priority Folders", if set) always come first
93
+ Among priorities: file with shortest path (by default) comes first
94
+ Among non-priorities: same rule (shortest path is used by default for in-group sorting)
95
+ If both files have the same path depth, the file with shortest filename wins the first place.
96
+
97
+ REMEMBER: In the end, there can be only one file/per group :)
98
+ ---
99
+
100
+
101
+ ### How to use cli-version
102
+ Examples:
103
+ ----------
104
+ Basic usage - find duplicates in Downloads folder
105
+ `onlyone -i ~/Downloads`
106
+
107
+ Filter files by size and extensions and find duplicates
108
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png`
109
+
110
+ Same as above + move duplicates to trash (with confirmation prompt)
111
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png --keep-one`
112
+
113
+ Same as above but without confirmation and with output to a file (for scripts)
114
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png --keep-one --force > ~/Downloads/report.txt`
115
+
116
+ Options:
117
+ ---------
118
+ -i, --input input folder
119
+ -m, --min-size min size filter
120
+ -M, --max-size max size filter
121
+ -x, --extensions, extension filter(comma separated)
122
+ -p, --priority-dirs priority dirs(comma or space separated)
123
+
124
+ --mode [fast, normal, full] searching mode (normal by default)
125
+ --sort [shortest-path, shortest-filename] sorting inside a group (shortest-path by default)
126
+
127
+ --keep-one Keep one file/per group and move the rest to trash (one confirmation)
128
+ --keep-one --force Keep one file/per group and move the rest to trash (no confirmation)
129
+ --verbose, -v Show detailed statistics and progress
130
+ --help, -h Show help file
131
+ ---
132
+
133
+ ### Boring stuff
134
+
135
+ ## Built With
136
+ - Python 3.x
137
+ - PySide6 (Qt)
138
+ - send2trash
139
+ - PIL/Pillow (for image handling)
140
+ - xxhash
141
+
142
+ ## TESTS
143
+ pytest tests/ -v
144
+
145
+ ## How to build with Pyinstaller
146
+ `pyinstaller --noconfirm --clean --noconsole \
147
+ --onefile --exclude-module=PySide6.QtNetwork main_window.py`
148
+
149
+ Or just download binary from [realeases](https://github.com/initumX/onlyone/releases)
150
+
151
+ Check out [website](https://initumx.github.io/onlyone/)
152
+
153
+ © 2026 initumX (initum.x@gmail.com)
154
+
155
+
156
+
157
+
158
+
159
+
160
+
@@ -0,0 +1,130 @@
1
+
2
+ # [OnlyOne](https://initumx.github.io/onlyone/)
3
+
4
+ ![screenshot](/deduplicator224.png "Main Window")
5
+
6
+ A PyQt-based tool for finding and removing duplicate files with advanced filtering and progress tracking.
7
+
8
+ *Note: GUI-version is "extra"(not mandatory part), so to install app with gui, use:
9
+
10
+ `pip install onlyone[gui]`
11
+
12
+ ### How to install and run
13
+ ### First Way - use venv (virtual environment)
14
+ 1. Create python virtual environment and go there:
15
+ python3 venv ~/onlyone && cd ~/onlyone
16
+ -----
17
+ 2. Activate it:
18
+ source ~/onlyone/bin/activate
19
+ -----
20
+ 3.Install onlyone into it:
21
+ pip install onlyone[gui]
22
+ -----
23
+ Done.
24
+ Now you can run `onlyone` or `onlyone-gui` commands from your virtual environment
25
+
26
+ ### Second Way - wait for build release :)
27
+
28
+ ### Features
29
+ Filters files by file size and extension
30
+ -------
31
+ Sorts files inside duplicate groups by path depth and filename length
32
+ ------
33
+ Supports deduplication modes: fast, normal, full
34
+ ------
35
+ Preview images directly in the interface (in gui-version)
36
+ ------
37
+ Progress tracking both for searching duplicates and deleting them (in gui-version)
38
+ -------
39
+ Statistics/report
40
+ ------
41
+ Context menu (open, reveal in explorer and delete file(s) options)
42
+ ------
43
+ One click deletion (delete all duplicates at once)
44
+ ------
45
+ Manage priority directories
46
+
47
+ ### How does it work?
48
+ 1. Recursively scans folder using filters (min/max size, extension)
49
+ 2. Apply the cheapest check first (compare by size)
50
+ 3. Further checking depends on mode:
51
+ a) "fast": checks hash-sum of first 64+ KB of files (false positives very possible)
52
+ b) "normal": checks hash-sum of 3 parts of the file: front -> middle -> end (generally reliable)
53
+ c) "full": checks hash-sum of front -> middle -> entire file (very slow for large files)
54
+ 4. Shows the list of groups sorted in descending order (groups with larger files come first).
55
+ --------
56
+ Files inside a group are sorted by path/filename length (you can regulate this).
57
+
58
+ ### Deleting all duplicates at once
59
+ The main principle: ALL files moved to trash EXCEPT the FIRST file in each group.
60
+ ---
61
+ Which file is "first" depends on sorting:
62
+ Priority files(files from "Priority Folders", if set) always come first
63
+ Among priorities: file with shortest path (by default) comes first
64
+ Among non-priorities: same rule (shortest path is used by default for in-group sorting)
65
+ If both files have the same path depth, the file with shortest filename wins the first place.
66
+
67
+ REMEMBER: In the end, there can be only one file/per group :)
68
+ ---
69
+
70
+
71
+ ### How to use cli-version
72
+ Examples:
73
+ ----------
74
+ Basic usage - find duplicates in Downloads folder
75
+ `onlyone -i ~/Downloads`
76
+
77
+ Filter files by size and extensions and find duplicates
78
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png`
79
+
80
+ Same as above + move duplicates to trash (with confirmation prompt)
81
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png --keep-one`
82
+
83
+ Same as above but without confirmation and with output to a file (for scripts)
84
+ `onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png --keep-one --force > ~/Downloads/report.txt`
85
+
86
+ Options:
87
+ ---------
88
+ -i, --input input folder
89
+ -m, --min-size min size filter
90
+ -M, --max-size max size filter
91
+ -x, --extensions, extension filter(comma separated)
92
+ -p, --priority-dirs priority dirs(comma or space separated)
93
+
94
+ --mode [fast, normal, full] searching mode (normal by default)
95
+ --sort [shortest-path, shortest-filename] sorting inside a group (shortest-path by default)
96
+
97
+ --keep-one Keep one file/per group and move the rest to trash (one confirmation)
98
+ --keep-one --force Keep one file/per group and move the rest to trash (no confirmation)
99
+ --verbose, -v Show detailed statistics and progress
100
+ --help, -h Show help file
101
+ ---
102
+
103
+ ### Boring stuff
104
+
105
+ ## Built With
106
+ - Python 3.x
107
+ - PySide6 (Qt)
108
+ - send2trash
109
+ - PIL/Pillow (for image handling)
110
+ - xxhash
111
+
112
+ ## TESTS
113
+ pytest tests/ -v
114
+
115
+ ## How to build with Pyinstaller
116
+ `pyinstaller --noconfirm --clean --noconsole \
117
+ --onefile --exclude-module=PySide6.QtNetwork main_window.py`
118
+
119
+ Or just download binary from [realeases](https://github.com/initumX/onlyone/releases)
120
+
121
+ Check out [website](https://initumx.github.io/onlyone/)
122
+
123
+ © 2026 initumX (initum.x@gmail.com)
124
+
125
+
126
+
127
+
128
+
129
+
130
+
@@ -0,0 +1,49 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "onlyone"
7
+ version = "2.4.3"
8
+ description = "Fast duplicate file finder with optional GUI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ {name = "initumX", email = "initum.x@gmail.com"}
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: X11 Applications :: Qt",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Utilities"
26
+ ]
27
+ dependencies = [
28
+ "xxhash>=3.0.0",
29
+ "send2trash>=1.8.0"
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ gui = [
34
+ "PySide6",
35
+ "Pillow>=9.0.0"
36
+ ]
37
+ dev = [
38
+ "pytest>=7.0",
39
+ "pytest-qt>=4.0",
40
+ "pytest-cov>=4.0"
41
+ ]
42
+
43
+ [project.scripts]
44
+ onlyone = "onlyone.cli:main"
45
+ onlyone-gui = "onlyone.gui.launcher:main"
46
+
47
+ [tool.setuptools.packages.find]
48
+ where = ["src"]
49
+ include = ["onlyone*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,43 @@
1
+ """
2
+ OnlyOne — fast duplicate file finder with optional GUI.
3
+
4
+ Core features:
5
+ - Three deduplication modes: FAST (size + front hash), NORMAL (size + 3 partial hashes), FULL (size + full content hash)
6
+ - Safe deletion to system trash (via send2trash)
7
+ - Optional GUI with PySide6 (install with [gui] extra)
8
+ - CLI interface for headless/server usage
9
+ """
10
+
11
+ # Get version
12
+ try:
13
+ from importlib.metadata import version as _version
14
+ __version__ = _version("onlyone")
15
+ except Exception:
16
+ try:
17
+ import tomllib # Python 3.11+
18
+ except ImportError:
19
+ import tomli as tomllib # Python < 3.11: pip install tomli
20
+
21
+ with open("pyproject.toml", "rb") as f:
22
+ __version__ = tomllib.load(f)["project"]["version"]
23
+
24
+ # Public API — only what users should import directly
25
+ from onlyone.commands import DeduplicationCommand
26
+ #from .cli import main as cli_main
27
+ from onlyone.core import DeduplicationParams, DeduplicationMode, SortOrder, File, DuplicateGroup
28
+ from onlyone.utils.convert_utils import ConvertUtils
29
+ from onlyone.services import DuplicateService
30
+ from onlyone.services.file_service import FileService
31
+
32
+ __all__ = [
33
+ "DeduplicationCommand",
34
+ "DeduplicationParams",
35
+ "DeduplicationMode",
36
+ "SortOrder",
37
+ "File",
38
+ "DuplicateGroup",
39
+ "ConvertUtils",
40
+ "DuplicateService",
41
+ "FileService",
42
+ "__version__",
43
+ ]