Ancestry Sync Display Individual.fh_lua--[[
@Title: Ancestry Sync - Display Individual
@Type: Standard
@Author: Mark Draper
@Contributor John Elvin
@Version: 1.0
@LastUpdated: 29 Mar 2026
@Licence: This plugin is copyright (c) 2026 Mark Draper and is licensed under the MIT License which
is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Displays Property Box Individual in Ancestry directly.
]]
fhInitialise(7, 0, 15)
require('luacom')
require('fhSQL')
require('iuplua')
function main()
-- get linked RM file from Ancestry Sync plugin options
local OptionsFile = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') ..
'\\Plugin Data\\Ancestry Synchronization.ini'
local RMfile = fhGetIniFileValue(OptionsFile, 'Files', 'File', 'text')
if RMfile == '' then
local msg = 'Please link the current project to Ancestry via the Ancestry Synchronization plugin.'
MessageBox(msg, 'OK', 'ERROR')
return
end
-- get currently selected Individual Record
local tblI = fhGetCurrentRecordSel('INDI')
if #tblI == 0 then
local msg = 'No Individual Record selected.'
MessageBox(msg, 'OK', 'ERROR')
return
elseif #tblI > 1 then
local msg = 'Multiple Individual Records selected.'
MessageBox(msg, 'OK', 'ERROR')
return
end
local UID = fhGetItemText(tblI[1], '~._UID'):gsub('-', '')
if UID == '' then
local msg = 'Selected Individual does not have an assigned UniqueID. ' ..
'Use the Ancestry Synchronization plugin to upload this individual to Ancestry.'
MessageBox(msg, 'OK', 'ERROR')
return
else
UID = FormatUID(UID)
end
local database = fhSQL.connectSQLite(RMfile)
local SQL = 'SELECT anID FROM PersonTable, AncestryTable WHERE PersonID = rmID AND UniqueID = "' .. UID .. '"'
local ResultSet = database:select(SQL)
local anID = ''
for I in ResultSet:rows() do
anID = I.anID
end
if anID == '' then
local msg = 'Selected Individual has not been uploaded to Ancestry.'
MessageBox(msg, 'OK', 'ERROR')
return
end
local PersonID, TreeID = anID:match('^(%d+)%:%d+%:(%d+)$')
if PersonID and TreeID then
local URL = 'https://www.ancestry.com/family-tree/tree/' .. TreeID .. '/person/' .. PersonID
fhShellExecute(URL)
else
local msg = 'Error determining Ancestry URL.' -- should never happen!
MessageBox(msg, 'OK', 'ERROR')
end
end
-- *********************************************************************
function FormatUID(UID)
-- calculate checksum using published method
local a = 0
local b = 0
for i = 1, 31, 2 do
local byte = UID:sub(i, i + 1)
local value = tonumber('0x' .. byte)
a = a + value
b = b + a
end
local cs1 = string.format('%x', a)
local cs2 = string.format('%x', b)
local checksum = cs1:sub(-2) .. cs2:sub(-2)
return UID .. checksum:upper()
end
-- *********************************************************************
function MessageBox(Message, Buttons, Icon, Title, Default)
-- replaces built-in function with custom version containing more options
-- set message
local msgdlg = iup.messagedlg{value = Message, buttons = Buttons, dialogtype = Icon,
title = Title or 'Ancestry Synchronization - View Individual', buttondefault = Default}
-- display message box and return selection
msgdlg:popup()
return tonumber(msgdlg.ButtonResponse)
end
-- *********************************************************************
main()
--[[
@Title: Ancestry Sync - Display Individual
@Type: Standard
@Author: Mark Draper
@Contributor John Elvin
@Version: 1.0
@LastUpdated: 29 Mar 2026
@Licence: This plugin is copyright (c) 2026 Mark Draper and is licensed under the MIT License which
is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Displays Property Box Individual in Ancestry directly.
]]
fhInitialise(7, 0, 15)
require('luacom')
require('fhSQL')
require('iuplua')
function main()
-- get linked RM file from Ancestry Sync plugin options
local OptionsFile = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') ..
'\\Plugin Data\\Ancestry Synchronization.ini'
local RMfile = fhGetIniFileValue(OptionsFile, 'Files', 'File', 'text')
if RMfile == '' then
local msg = 'Please link the current project to Ancestry via the Ancestry Synchronization plugin.'
MessageBox(msg, 'OK', 'ERROR')
return
end
-- get currently selected Individual Record
local tblI = fhGetCurrentRecordSel('INDI')
if #tblI == 0 then
local msg = 'No Individual Record selected.'
MessageBox(msg, 'OK', 'ERROR')
return
elseif #tblI > 1 then
local msg = 'Multiple Individual Records selected.'
MessageBox(msg, 'OK', 'ERROR')
return
end
local UID = fhGetItemText(tblI[1], '~._UID'):gsub('-', '')
if UID == '' then
local msg = 'Selected Individual does not have an assigned UniqueID. ' ..
'Use the Ancestry Synchronization plugin to upload this individual to Ancestry.'
MessageBox(msg, 'OK', 'ERROR')
return
else
UID = FormatUID(UID)
end
local database = fhSQL.connectSQLite(RMfile)
local SQL = 'SELECT anID FROM PersonTable, AncestryTable WHERE PersonID = rmID AND UniqueID = "' .. UID .. '"'
local ResultSet = database:select(SQL)
local anID = ''
for I in ResultSet:rows() do
anID = I.anID
end
if anID == '' then
local msg = 'Selected Individual has not been uploaded to Ancestry.'
MessageBox(msg, 'OK', 'ERROR')
return
end
local PersonID, TreeID = anID:match('^(%d+)%:%d+%:(%d+)$')
if PersonID and TreeID then
local URL = 'https://www.ancestry.com/family-tree/tree/' .. TreeID .. '/person/' .. PersonID
fhShellExecute(URL)
else
local msg = 'Error determining Ancestry URL.' -- should never happen!
MessageBox(msg, 'OK', 'ERROR')
end
end
-- *********************************************************************
function FormatUID(UID)
-- calculate checksum using published method
local a = 0
local b = 0
for i = 1, 31, 2 do
local byte = UID:sub(i, i + 1)
local value = tonumber('0x' .. byte)
a = a + value
b = b + a
end
local cs1 = string.format('%x', a)
local cs2 = string.format('%x', b)
local checksum = cs1:sub(-2) .. cs2:sub(-2)
return UID .. checksum:upper()
end
-- *********************************************************************
function MessageBox(Message, Buttons, Icon, Title, Default)
-- replaces built-in function with custom version containing more options
-- set message
local msgdlg = iup.messagedlg{value = Message, buttons = Buttons, dialogtype = Icon,
title = Title or 'Ancestry Synchronization - View Individual', buttondefault = Default}
-- display message box and return selection
msgdlg:popup()
return tonumber(msgdlg.ButtonResponse)
end
-- *********************************************************************
main()
Source:Ancestry-Sync-Display-Individual.fh_lua