I am building a complete-as-possible media manager in batch. It watches your qbittorrent downloads, processes them and sorts the media to your collection.

This is the main part of the script which calls for seven other scripts for additional tasks like safe renaming, adding subtitles, sorting videos and detecting duplicate files by name.

@wmic process where name="cmd.exe" call setpriority "idle" >nul & set "loop=60" & cls
@echo RUN: run script now - TIMER: change this delay - DUPES: duplicates check - CLEAR: clear screen

:: launcher
@d:\other\scripts\colorx -c 08
@choice /t %loop% /c rtdc /n /d r /m "wait %loop%s or enter command [R]un, [T]imer, [D]upes or [C]lear? "
@if "%errorlevel%"=="2" set /p loop="how many seconds to wait between every job run? " && goto loop
@if "%errorlevel%"=="3" for /f "delims=" %%d in ('dir d:\videos /a:d /b /s ^| sort /r') do @call d:\other\scripts\sortdupes "%%d"
@if "%errorlevel%"=="4" cls && goto loop
@d:\other\scripts\colorx -c 08

:: downloads manager (add seeding support)
@cd /d e:\works\source
@if /i not "%cd%"=="e:\works\source" echo invalid starting dir. && exit /b
@for /r %%u in (.unwanted) do @rd /s /q "%%u" 2>nul
@for %%s in (*.*) do @if not "%%~xs"==".!qB" md "%%~ns" & move "%%s" "%%~ns" >nul 2>nul && echo nested single file "%%~nxs"
@for /f "delims=" %%t in ('dir e:\works\source /b /a:d') do @set "releasedir=%%~nxt" & call :loot
@d:\other\scripts\colorx -c 08
@for /f "delims=" %%e in ('dir e:\works\source /a:d /b /s ^| sort /r') do @rd "%%e" 2>nul && echo deleted empty directory %%~ne

:: collection manager
@cd /d d:\videos
@if /i not "%cd%"=="d:\videos" echo cannot sort. no access to d:\videos && goto loop
@dir d:\videos\* /a-d >nul 2>nul && call d:\other\scripts\sortroot.cmd
@dir d:\videos\series\* /a-d >nul 2>nul && call d:\other\scripts\sortseries.cmd
@dir d:\videos\shorts\* /a-d >nul 2>nul && call d:\other\scripts\sortshorts.cmd
@dir d:\videos\movies\* /a-d >nul 2>nul && call d:\other\scripts\sortmovies.cmd
@goto loop

:: precautions
@d:\other\scripts\colorx -c 07
@cd /d "e:\works\source\%releasedir%" 2>nul
@if /i not "%cd%"=="e:\works\source\%releasedir%" echo no access to "e:\works\source\%releasedir%" && goto next
@dir *.!qb /s /b >nul 2>nul && goto next
@set "media=none" & dir * /s /a-d >nul 2>nul && set media=misc
@if "%media%"=="none" goto next

:: preparations
@echo. & echo found complete "%releasedir%"
@attrib -s -h *.* /s >nul
@for /r %%r in (*.zip *.7z) do @d:\other\scripts\loot\tools\7z x -y "%%r" >nul && del "%%r" && echo unpacked "%%~nxr"
@attrib -s -h *.* /s >nul
@set extensions=*.mp4 *.mkv *.m4v *.avi *.flv *.mpg *.mpeg *.mpe *.wmv *.mov *.ts *.m2ts *.vob *.3gp *.rm
@dir %extensions% /s >nul 2>nul && set media=video
@dir /s *.mp3 >nul 2>nul && set media=audio

:: all non-audio/video release handler
@if "%media%"=="misc" cd .. && robocopy "e:\works\source\%releasedir%" "d:\other\works\%releasedir%" /e /move >nul
@if "%media%"=="misc" if not exist "d:\other\works\%releasedir%" echo moved other "%releasedir%" && goto next
@if "%media%"=="misc" if exist "d:\other\works\%releasedir%" echo failed moving other "%releasedir%" && goto next

:: audio part handler (add unrated tag)
@for /r %%m in (*.mp3) do @d:\other\scripts\mp3gain /r /c /f "%%m" >nul && echo track gain applied to "%%~nxm"
@if "%media%"=="audio" d:\other\scripts\delay 1 && if not exist d:\music\new md d:\music\new
@for /r %%m in (*.mp3) do @move "%%m" d:\music\new >nul && echo moved mp3 "%%~nxm"

:: video part handler
@dir %extensions% /s >nul 2>nul && set media=video
@for /r %%s in (*sample*.m* *sample*.avi etrg.* rarbg.*) do @del "%%s" && echo deleted unwanted video "%%~nxs"
@for /r %%v in (%extensions%) do @call d:\other\scripts\lootsubs "%%v"
@for /r %%v in (%extensions%) do @call d:\other\scripts\lootname "%%v" "%releasedir%"
@d:\other\scripts\colorx -c 07 & cd /d "e:\works\source\%releasedir%"
@for /r %%v in (%extensions%) do @move "%%v" d:\videos >nul && echo "d:\videos\%%~nxv"

:: recheck and delete remains
@dir *.mp3 %extensions% /s >nul 2>nul && echo media files still remain. maybe the disk is full? && goto next
@if not "%media%"=="misc" cd .. && rmdir /s /q "e:\works\source\%releasedir%" && echo deleted folder "%releasedir%"

Should I describe in detail what everything does? I will be posting the other scripts as they become relevant so just ask for them if curious.


To answer your question, your code should be descriptive enough that it would read like English and make sense if someone reads it from top to bottom. You should only ever need to add descriptions if the code is confusing or doesn't quite make sense why you're doing something 'like that'.

I'd like to offer some suggestions:

  • Put @echo off at the top. You can then remove all the @ at the start of each line
  • Use choice instead of set /p (more options and cleaner, no leftover environment variables)
  • Instead of >nul 2>nul, use >NUL 2>&1 (helps to understand the mechanisms behind the 3 types and can improve your understanding of redirection)
  • Regarding using call, why not use "modules" inside your batch instead of separate files?

    For example:

    :: collection manager
    :: skipping...
    call :sortseries d:\videos\series
    call :sortshorts d:\videos\shorts
    call :sortmovies d:\videos\movies
    goto loop
    echo looking at folder %1
    :: do something here and return to caller/next line
    goto :eof
    :: etc do the same here
    :: at the end of this modules, call goto eof
    goto :eof

    After all, you want all this in the same script, correct? Furthermore, it helps to notice repeated patterns and you can refactor all these modules down to their common parts with injecting variables to modify behaviour.

    Something like this:

    call :sortseries d:\videos\series
    call :sortshorts d:\videos\shorts
    call :sortmovies d:\videos\movies
    call :sortmedia %1 x:\output\series
    goto :eof
    call :sortmedia %1 x:\output\shorts
    goto :eof
    :: etc
    :: this is where we do the common actions for %1 and %2
    :: where %1 is the input path from the first call, and 
    :: %2 is the output path from the second call.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.