Created
January 31, 2018 23:53
-
-
Save The0x539/39ac92ba3fa8d328969eb3c8bcbe29eb to your computer and use it in GitHub Desktop.
Recursively generate checksums of all videos in a directory on Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--Run an OS command, returning its output rather than its exit status. | |
local function run(cmd,mode) | |
local prog = io.popen(cmd) | |
local output | |
if mode == 1 then --String of full output | |
output = prog:read("*all"):sub(1,-2) | |
prog:close() | |
elseif mode == 2 then --Table of each line | |
output = {} | |
for line in prog:lines() do | |
table.insert(output,line) | |
end | |
prog:close() | |
elseif mode == 3 then --Iterator over lines of output | |
output = prog:lines() | |
else | |
error("Unknown mode") | |
end | |
return output | |
end | |
--Decide where the root of this is going to happen | |
local toplevel | |
local arg = select(1,...) | |
if arg == nil then | |
toplevel = "C:\\Users\\Andrew\\Media\\" | |
else | |
toplevel = run("cd /D "..arg.." && cd",1)..'\\' | |
end | |
--Determine where the home folder is, so it can be abbreviated to ~ | |
local USERPROFILE = run("echo %USERPROFILE%",1) | |
function main(dir) | |
--Figure out where we are | |
dir = dir or toplevel | |
dir = dir:gsub("\\\\",'\\') | |
local pwd = dir:gsub(USERPROFILE,'~') | |
print(pwd) | |
--Read existing SHA256SUMS file to build a dictionary mapping filenames to hashes | |
local checksums = {} | |
local sums = io.open(dir.."SHA256SUMS",'r') | |
if sums ~= nil then | |
for line in sums:lines() do | |
local checksum = line:sub(1,64) | |
local filename = line:sub(66) | |
checksums[filename] = checksum | |
end | |
sums:close() | |
end | |
--List directory contents to build a (sorted) list of files to be checksummed | |
local filenames = {} | |
for file in run([[dir /B /A:-D "]]..dir..[["]],3) do | |
if file:find("%.mkv$") or file:find("%.mp4$") then | |
table.insert(filenames,file) | |
end | |
end | |
table.sort(filenames) | |
--Calculate checksums for any new files | |
local newFiles = false | |
for _,file in ipairs(filenames) do | |
if not checksums[file] then | |
io.write("Generating checksum for new file "..dir..file.."...") | |
out = run([[sha256sum.exe "]]..dir..file..[["]],1) | |
checksums[file] = out:sub(2,65) | |
print("done.") | |
newFiles = true | |
end | |
end | |
--If there were any new files, rebuild SHA256SUMS using the dictionary and the sorted list | |
if newFiles then | |
io.write("Rewriting "..dir.."SHA256SUMS...") | |
os.execute([[del /A "]]..dir..[[SHA256SUMS" 2>nul]]) | |
local sums,err = io.open(dir.."SHA256SUMS",'w') | |
for _,file in ipairs(filenames) do | |
local sum = checksums[file] | |
sums:write(sum..' '..file..'\n') | |
end | |
sums:close() | |
os.execute([[attrib +h "]]..dir..[[SHA256SUMS"]]) | |
print("done.") | |
end | |
--Perform the above steps for all subdirectories of the current directory | |
for subdir in run([[dir /B /A:D "]]..dir..[["]],3) do | |
main(dir..subdir..'\\') | |
end | |
end | |
--do the thing | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment