feat: --selected mode — process individual files (context menu + SendTo)

This commit is contained in:
admin committed 2026-06-29 15:36:02 +02:00
1 parent 33c33d08f0
commit 051d12eb3c
5 files changed
+148 -76

No files matched your search

+11 -4
View File
@@ -72,7 +72,14 @@ install.bat
uninstall-context-menu.bat
```
После установки в контекстном меню два пункта:
- **«Raskidator-3000»** — сортировка (реальное перемещение)
- **«Raskidator-3000 (dry-run)»** — только показать что будет перемещено
- **Работает в библиотеках** (Pictures, Music, Videos, Documents)
После установки:
| Действие | Результат |
|----------|-----------|
| **ПКМ на папке** → Raskidator-3000 | Сортировка всей папки |
| **ПКМ на папке** → Raskidator-3000 (dry-run) | Только показать что будет |
| **ПКМ на файле** → Raskidator-3000 | Сортировать только этот файл |
| **Выделить файлы** → Отправить → Raskidator-3000 | Сортировать только выделенные файлы |
| Работает в библиотеках (Pictures, Music, Videos) | |
При сортировке отдельных файлов (`--selected`) лимит `MAX_FILES` игнорируется — обрабатываются все переданные файлы.
+63 -27
View File
@@ -18,54 +18,90 @@ echo.
set "BAT_PATH=%BAT_DIR%\raskidator.bat"
set "ICON=%BAT_DIR%\raskidator.bat,0"
:: Directory\Background\shell - right-click in empty folder space
echo [1/3] Adding to folder background context menu...
:: ── 1. Папки (правая кнопка на папке) ─────────────────────────────
echo [1/4] Folder context menu...
:: Обычный запуск
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000" /ve /t REG_SZ /d "Raskidator-3000" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" \"%%V\"" /f
:: Пробный запуск (dry-run)
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --dry-run \"%%V\"" /f
echo [+] Directory\Background - done (2 entries)
echo.
:: Directory\shell - right-click on folder
echo [2/3] Adding to folder right-click menu...
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000" /ve /t REG_SZ /d "Raskidator-3000" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" \"%%1\"" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --dry-run \"%%1\"" /f
echo [+] Directory\shell - done (2 entries)
echo.
:: LibraryFolder\Background - Pictures, Music, Videos...
echo [3/3] Adding to libraries (Pictures, Music, Videos)...
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000" /ve /t REG_SZ /d "Raskidator-3000" /f
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" \"%%V\"" /f
:: Пробный запуск (dry-run)
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --dry-run \"%%V\"" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --dry-run \"%%1\"" /f
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --dry-run \"%%V\"" /f
echo [+] LibraryFolder\Background - done (2 entries)
echo [+] Folder context menu — done
echo.
:: ── 2. Файлы (правая кнопка на 1 файле) ──────────────────────────
echo [2/4] File context menu...
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000" /ve /t REG_SZ /d "Raskidator-3000" /f
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --selected \"%%1\"" /f
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000DryRun" /ve /t REG_SZ /d "Raskidator-3000 (dry-run)" /f
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000DryRun" /v Icon /t REG_SZ /d "%ICON%" /f
reg add "HKEY_CLASSES_ROOT\*\shell\Raskidator3000DryRun\command" /ve /t REG_SZ /d "\"%BAT_PATH%\" --selected --dry-run \"%%1\"" /f
echo [+] File context menu — done
echo.
:: ── 3. SendTo (несколько выделенных файлов) ──────────────────────
echo [3/4] SendTo (multi-file)..
set "SENDTO=%APPDATA%\Microsoft\Windows\SendTo"
:: Основной
del "%SENDTO%\Raskidator-3000.bat" 2>nul
> "%SENDTO%\Raskidator-3000.bat" (
echo @echo off
echo chcp 65001 ^>nul
echo call "%BAT_PATH%" --selected %%*
)
:: Пробный (dry-run)
del "%SENDTO%\Raskidator-3000 (dry-run).bat" 2>nul
> "%SENDTO%\Raskidator-3000 (dry-run).bat" (
echo @echo off
echo chcp 65001 ^>nul
echo call "%BAT_PATH%" --selected --dry-run %%*
)
echo [+] SendTo — done
echo.
:: ── 4. Удаление старых версий ──────────────────────────────────────
echo [4/4] Cleaning up old entries...
reg delete "HKEY_CLASSES_ROOT\*\shell\Raskidator3000" /f >nul 2>&1
reg delete "HKEY_CLASSES_ROOT\*\shell\Raskidator3000DryRun" /f >nul 2>&1
echo [+] Cleanup — done
echo.
echo ========================================
echo Installation complete!
echo Right-click any folder ->
echo Raskidator-3000 — сортировка
echo Raskidator-3000 (dry-run) — пробный запуск
echo.
echo ПКМ на папке — Raskidator-3000
echo ПКМ на файле — Raskidator-3000
echo Отправить ^> файлы — Raskidator-3000 (любое кол-во)
echo ========================================
pause
+36 -5
View File
@@ -317,6 +317,7 @@ def organize(
group_by: str = 'day',
quiet: bool = False,
max_files: int | None = None,
selected_files: list[Path] | None = None,
) -> int:
"""Scan *folder* and sort images into year/month[/day] subfolders.
@@ -327,6 +328,9 @@ def organize(
return 1
# ── Scan ────────────────────────────────────────────────────────────────
if selected_files is not None:
files = [f for f in selected_files if f.suffix.lower() in EXTENSIONS]
else:
files: list[Path] = [
f for f in folder.iterdir()
if f.is_file() and f.suffix.lower() in EXTENSIONS
@@ -626,10 +630,16 @@ def main() -> None:
add_help=True,
)
parser.add_argument(
'path',
nargs='?',
'paths',
nargs='*',
default=None,
help='Folder to scan (default: current directory)',
help='Folder to scan, or file(s) with --selected',
)
parser.add_argument(
'--selected',
action='store_true',
default=False,
help='Process specified files instead of scanning a folder',
)
parser.add_argument(
'--no-color',
@@ -666,7 +676,29 @@ def main() -> None:
# If --max-files not set, use MAX_FILES constant
max_files = args.max_files if args.max_files is not None else MAX_FILES
folder = Path(args.path) if args.path else Path.cwd()
if args.selected:
# Process specified files (from SendTo or file selection)
file_paths = [Path(p) for p in args.paths if Path(p).is_file()]
if not file_paths:
print(_c(' No valid files specified.', _YELLOW, no_color=args.no_color))
sys.exit(1)
max_files = len(file_paths) # process exactly the selected files
print(_c('Raskidator-3000', _BOLD, no_color=args.no_color))
print(f' Selected files: {len(file_paths)}')
if args.dry_run:
print(_c(' Mode: DRY-RUN', _CYAN, no_color=args.no_color))
print()
rc = organize(
file_paths[0].parent, # use parent folder as base
dry_run=args.dry_run,
no_color=args.no_color,
group_by=args.group_by,
quiet=args.quiet,
max_files=max_files,
selected_files=file_paths,
)
else:
folder = Path(args.paths[0]) if args.paths else Path.cwd()
print(_c('Raskidator-3000', _BOLD, no_color=args.no_color))
print(f' Folder: {folder.resolve()}')
if args.dry_run:
@@ -674,7 +706,6 @@ def main() -> None:
if max_files:
print(f' Max files: {max_files}')
print()
rc = organize(
folder,
dry_run=args.dry_run,
+21 -30
View File
@@ -10,41 +10,32 @@ echo.
:: Сохраняем путь к папке с батником ДО shift (shift меняет %0)
set "BAT_DIR=%~dp0"
:: Определяем режим (--dry-run или обычный)
:: Определяем режимы
set "DRY="
if /i "%~1"=="--dry-run" (
set "DRY=--dry-run"
shift
)
set "SELECTED="
if /i "%~1"=="--selected" set "SELECTED=--selected" & shift
if /i "%~1"=="--dry-run" set "DRY=--dry-run" & shift
:: Определяем папку, которую обрабатываем
if "%~1"=="" (
set "TARGET=%CD%"
if not "%SELECTED%"=="" (
:: Режим выбранных файлов (SendTo / контекстное меню)
echo Выбранные файлы: %*
echo.
python "%BAT_DIR%organize.py" --selected %DRY% %*
if %errorlevel% equ 0 goto :end
py -3 "%BAT_DIR%organize.py" --selected %DRY% %*
if %errorlevel% equ 0 goto :end
) else (
set "TARGET=%~1"
:: Режим папки
if "%~1"=="" (set "TARGET=%CD%") else (set "TARGET=%~1")
echo Папка: %TARGET%
if not "%DRY%"=="" echo Режим: ПРОБНЫЙ (dry-run)
echo.
python "%BAT_DIR%organize.py" %DRY% "%TARGET%"
if %errorlevel% equ 0 goto :end
py -3 "%BAT_DIR%organize.py" %DRY% "%TARGET%"
if %errorlevel% equ 0 goto :end
)
echo Папка: %TARGET%
if not "%DRY%"=="" echo Режим: ПРОБНЫЙ (dry-run)
echo.
:: Проверяем, существует ли скрипт
if exist "%BAT_DIR%organize.py" (
set "SCRIPT=%BAT_DIR%organize.py"
) else (
echo [ОШИБКА] Не найден organize.py рядом с батником.
echo Ожидаемый путь: %BAT_DIR%organize.py
goto :end
)
:: Пробуем python (наиболее распространён)
python "%SCRIPT%" %DRY% "%TARGET%"
if %errorlevel% equ 0 goto :end
:: Если python не сработал — пробуем py -3 (Python Launcher)
py -3 "%SCRIPT%" %DRY% "%TARGET%"
if %errorlevel% equ 0 goto :end
:: Если оба не сработали
echo.
echo [ОШИБКА] Python не найден. Установи Python с python.org
+17 -10
View File
@@ -8,22 +8,29 @@ echo Raskidator-3000
echo ========================================
echo.
echo [1/3] Removing from folder background context menu...
echo [1/4] Removing from folder context menus...
reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000" /f >nul 2>&1
reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\Raskidator3000DryRun" /f >nul 2>&1
if %errorlevel% equ 0 (echo [+] Directory\Background - removed) else (echo [+] Directory\Background - done)
echo.
echo [2/3] Removing from folder right-click menu...
reg delete "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000" /f >nul 2>&1
reg delete "HKEY_CLASSES_ROOT\Directory\shell\Raskidator3000DryRun" /f >nul 2>&1
if %errorlevel% equ 0 (echo [+] Directory\shell - removed) else (echo [+] Directory\shell - done)
echo.
echo [3/3] Removing from libraries (Pictures, Music, Videos)...
reg delete "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000" /f >nul 2>&1
reg delete "HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Raskidator3000DryRun" /f >nul 2>&1
if %errorlevel% equ 0 (echo [+] LibraryFolder\Background - removed) else (echo [+] LibraryFolder\Background - done)
echo [+] Folder menus — done
echo.
echo [2/4] Removing from file context menus...
reg delete "HKEY_CLASSES_ROOT\*\shell\Raskidator3000" /f >nul 2>&1
reg delete "HKEY_CLASSES_ROOT\*\shell\Raskidator3000DryRun" /f >nul 2>&1
echo [+] File menus — done
echo.
echo [3/4] Removing SendTo entries...
del "%APPDATA%\Microsoft\Windows\SendTo\Raskidator-3000.bat" 2>nul
del "%APPDATA%\Microsoft\Windows\SendTo\Raskidator-3000 (dry-run).bat" 2>nul
echo [+] SendTo — done
echo.
echo [4/4] Cleanup complete
echo.
echo ========================================