Check for Broken Media Links.fh_lua

--[[
@Title:			Check for Broken Media Links
@Type:				Standard
@Author:			Mike Tate
@Contributors:	
@Version:			1.2
@Keywords:		
@LastUpdated:	26 Oct 2022
@Licence:			This plugin is copyright (c) 2022 Mike Tate & contributors and is licensed under the MIT License which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description:	Checks all media records and local media objects in the Project for broken/missing file links.
@V1.2:				Use the File System Object library to check files exist;
@V1.1:				FH V7 Lua 3.5 IUP 3.28 compatibility; Cater for % in Project Folder Path;
@V1.0:				First published version including support for Unicode UTF-8 filenames;
]]

local strTitle = "Check for Broken Media Links  1.2"

require("luacom")												-- To access COM subsystem and create File System Object
FSO = luacom.CreateObject("Scripting.FileSystemObject")

if fhGetAppVersion() > 5 then								-- Cater for Unicode UTF-8 from FH Version 6 onwards
	fhSetStringEncoding("UTF-8")
end

-------------------------------------- Main Function

local tblMediaPtr = {}											-- Result Set tables
local tblRecordId = {}
local tblFilePath = {}

function Main()
	local strBroke = "No"
	SearchMedia()
	fhOutputResultSetTitles(strTitle)
	if #tblMediaPtr > 0 then
		strBroke = tostring(#tblMediaPtr)
		fhOutputResultSetColumn("Media" ,"item"   ,tblMediaPtr,#tblMediaPtr,250)
		fhOutputResultSetColumn("Rec Id","integer",tblRecordId,#tblMediaPtr, 35)
		fhOutputResultSetColumn("File"  ,"text"   ,tblFilePath,#tblMediaPtr,450)
	else
		fhOutputResultSetColumn("Media","text",{"No Broken Media Links Found"},1,100)
	end
	fhMessageBox(strBroke.." Broken Media Links Found","MB_OK","MB_ICONINFORMATION")
end -- function Main

-------------------------------------- Custom Functions

function SearchMedia()
	local strRoot = fhGetContextInfo("CI_PROJECT_DATA_FOLDER"):gsub("%%","%%%%") -- Cater for % in Project Folder Path
	local intType = fhGetRecordTypeCount()					-- Get count of record types
	local ptrAny = fhNewItemPtr()
	for intRec = 1, intType do								-- Loop through record types
		ptrAny:MoveToFirstRecord(fhGetRecordTypeTag(intRec))
		while ptrAny:IsNotNull() do
			if fhGetTag(ptrAny):match("^_?FILE$") then	-- Found _FILE or FILE link tag
				local strFile = fhGetValueAsText(ptrAny)	-- Create absolute file path
				local strPath = strFile:gsub("^([Mm][Ee][Dd][Ii][Aa])\\",strRoot.."\\%1\\")
				if #strPath > 0 and not FSO:FileExists(strPath) then
					local ptrObje = fhNewItemPtr()			-- Broken file link found
					ptrObje:MoveToParentItem(ptrAny)
					table.insert(tblMediaPtr,ptrObje:Clone())
					table.insert(tblRecordId,fhGetRecordId(ptrObje))
					table.insert(tblFilePath,strFile)
				end
			end
			ptrAny:MoveNextSpecial()
		end
	end
end -- function SearchMedia

-------------------------------------- Call Main Function

Main()

Source:Check-for-Broken-Media-Links-3.fh_lua