Skip to content

Instantly share code, notes, and snippets.

@The0x539
Created January 31, 2018 23:53
Show Gist options
  • Save The0x539/39ac92ba3fa8d328969eb3c8bcbe29eb to your computer and use it in GitHub Desktop.
Save The0x539/39ac92ba3fa8d328969eb3c8bcbe29eb to your computer and use it in GitHub Desktop.
Recursively generate checksums of all videos in a directory on Windows
--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