Metadata-Version: 2.4
Name: onlyone
Version: 2.5.2
Summary: Fast duplicate file finder with optional GUI
Author-email: initumX <initum.x@gmail.com>
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: xxhash>=3.0.0
Requires-Dist: send2trash>=1.8.0
Provides-Extra: gui
Requires-Dist: PySide6; extra == "gui"
Requires-Dist: Pillow>=9.0.0; extra == "gui"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-qt>=4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Dynamic: license-file


# [OnlyOne](https://github.com/initumX/onlyone)

![screenshot](https://raw.githubusercontent.com/initumX/onlyone/refs/heads/main/onlyone251.png)

A PyQt-based tool for finding and removing duplicate files with advanced filtering and progress tracking.

*Note: GUI-version is "extra"(not mandatory part), so to install app with gui, use:

`pip install onlyone[gui]`

## How to install and run
  1. Create python virtual environment and go there: `python3 venv ~/onlyone && cd ~/onlyone` 
  2. Activate it: `source ~/onlyone/bin/activate`
  3. Install onlyone into it: `pip install onlyone[gui]`
  4. Run the app: `onlyone-gui`  or `onlyone`(for cli)  
Note: Newest OnlyOne requires at least **python 3.8** (but higher version is recommended)

##  [GitHub](https://github.com/initumX/onlyone)   
* You can download binary for linux and windows from [github release](https://github.com/initumX/onlyone/releases)  
* If you like this app, push a star on its [github page](https://github.com/initumX/onlyone)  

## [Changelog](https://github.com/initumX/onlyone/blob/main/CHANGELOG.md)
Important notes:  
* List elements, separated by comma don't work anymore. Use space as separator:  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg .png` <- Ok  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg,.png` <- Wrong!  
The same thing with priority dirs and excluded dirs (for cli).  
If path contains space, just backslash space inside path:  
`onlyone -i .~/Downloads -x .jpg .png --excluded-dirs ~/Downloads/spaced\ folder\ one`
* Now extensions can work also in a blacklist mode (just use ^ as the first element of list for that):  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x ^ .jpg .png` <- Any extension except of jpg and png  
* Now you can use multiple directories(space separated) for input:  
`onlyone -i ~/Downloads ~/Documents ~/Videos` 
* A lot of changing in OnlyOne 2.5.0 cli (see changelog file)  

### Features
* Filtering by file size and extension
* Sorting inside duplicate groups 
* Supporting various deduplication modes
* Preview images/pdf directly in the interface
* Context menu(open/delete/reveal in explorer)
* Progress tracking (in gui-version)
* One click deletion (delete all duplicates at once)
* Priority and excluded directories functionality
* Statistics/report

### How does it work?
1. Recursively scans folder using filters (min/max size, extension)
2. Applies one of the initial grouping ways from "boosting" option (size, size+extension, etc)
3. Further checking depends on mode:
   * "fast": checks hash-sum of first 128+ KB (false positives very possible)
   * "normal": checks hash-sum of 3 parts of the file: front -> middle -> end (generally reliable)
   * "full": checks hash-sum of front -> middle -> entire file (very slow for large files)  
4. Shows the list of groups sorted in descending order (groups with larger files come first).   
   **Files inside a group are sorted by path/filename length (you can regulate this).

### Deleting all duplicates at once
The main principle: ALL files moved to trash EXCEPT the FIRST file in each group.  
Which file is "first" depends on sorting:  
* Priority files(files from "Priority Folders", if set) always come first
  * Among priorities: file with shortest path (by default) comes first
* Among non-priorities: same rule (shortest path is used by default for in-group sorting)  
If both files have the same path depth, the file with shortest filename wins the first place.

      REMEMBER: In the end, there can be only one file/per group :)
---


### How to use cli-version
Examples:  
Find and show duplicates in Downloads, Documents and Videos folders:  
`onlyone -i ~/Downloads ~/Documents ~/Videos`  

Filter files by size and extensions and find duplicates:  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg .png`

Filter files by size, exclude extensions jpg and png, find duplicates:  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x ^ .jpg .png`

Filter files by size, include extensions jpg and png only, find duplicates:  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg .png`

Same as above + move duplicates to trash (with confirmation prompt):  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg .png --keep-one`

Same as above but without confirmation and with output to a file (for scripts):  
`onlyone -i .~/Downloads -m 500KB -M 10MB -x .jpg .png --keep-one --force > ~/Downloads/report.txt`
    
Options:  
`-i, --input`          input folder(or multiple space separated folders)  
`-m, --min-size`       min size filter  
`-M, --max-size`       max size filter  
`-x, --extensions`     extension filter (space separated, start with ^ to make extensions list work in "blacklist" mode)    
`-p, --priority-dirs`  priority dirs (space separated). Files from here are prioritized to keep (come first in each group)   
`--excluded-dirs`     excluded/ignored dirs (space separated)  
`--boost {size,extension,filename,fuzzy}`  Rule for initial file grouping:  
* `size` Group files of the same size only (default)  
* `extension`  Group files of the same size and extension  
* `filename`   Group files of the same size and filename  
* `fuzzy`      Group files of the same size and similar filename

`**Groups formed above will be checked (hash-checking) in further stages`  

`--mode {fast, normal, full}` checking mode (normal by default)
* `fast`    check only by hashsum from the front part of file  
* `normal`  check by hashsum from 3 parts of file  
* `full`    check by hashsum from 2 part + whole file hashsum  

`--sort {shortest-path, shortest-filename}` sorting inside a group (shortest-path by default)  
`--dry-run`             Test running  
`--keep-one`            Keep one file/per group and move the rest to trash (one confirmation)  
`--keep-one --force`    Keep one file/per group and move the rest to trash (no confirmation)  
`--ascii`               ASCII-compilant output  
`--stats`               Show stats  
`--version, -v`         Show version and exit   
`--help, -h`            Show help file  

### TESTS
`pytest tests/ -v` 

### Build with Pyinstaller
`pyinstaller --noconfirm --clean --noconsole --copy-metadata=onlyone --onefile --paths ./src --name=OnlyOne --exclude-module=PySide6.QtNetwork ./src/onlyone/gui/launcher.py` 

### Built With  
- Python 3.x
- PySide6 (Qt)
- send2trash
- PIL/Pillow (for image handling)
- xxhash

### LINKS
 * [GitHub Page](https://github.com/initumX/onlyone)
 * [Releases](https://github.com/initumX/onlyone/releases)
 * [PyPI](https://pypi.org/project/onlyone/)
 * email (initum.x@gmail.com)

© 2026 initumX
