Backup Family Historian Settings.fh_lua--[[
@Title: Backup Family Historian Settings
@Author: Jane Taubman
@LastUpdated: May 2012
@Version: 1.3
@Description: Creates a Backup of the Family Historian Settings to a backup location of your choice.
@changes:
1.1 Changed to use the Lua Path to find the FH Program Data folder so it works with XP.
1.1 Changed to simply return when No is selected on the first prompt.
1.2 Use the fhGetContextInfo("CI_APP_DATA_FOLDER") now it's been reinstated.
1.3 Don't save preferences when in Standalone Gedcom mode.
]]
require "iuplua" -- For directory dialog
require "lfs" -- To access the directory structure
------------------------------------------------
-- dirtree
-- Returns a directory tree.
------------------------------------------------
function dirtree(dir)
assert(dir and dir ~= "", "directory parameter is missing or empty")
if string.sub(dir, -1) == "/" then
dir=string.sub(dir, 1, -2)
end
local function yieldtree(dir)
for entry in lfs.dir(dir) do
if entry ~= "." and entry ~= ".." then
entry=dir.."\\"..entry
local attr=lfs.attributes(entry)
coroutine.yield(entry,attr)
if attr.mode == "directory" then
yieldtree(entry)
end
end
end
end
return coroutine.wrap(function() yieldtree(dir) end)
end
------------------------------------------------
-- file_exists
-- Checks if a file exists
------------------------------------------------
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true
else
return false
end
end
------------------------------------------------
-- CopyFile
-- Copies a file
-- @requires file_exists() function
-- @requires "LFS" module
-- @Parms strfromfile File to copy from
-- @Parms strtofile File to copy to
-- @Parms bReplace Boolean for existing to files true=replace file, false=skip
------------------------------------------------
function CopyFile(strfromfile,strtofile,bReplace)
if not(bReplace) then
if file_exists(strtofile) then
return false
end
end
local inp = assert(io.open(strfromfile, "rb"))
local out = assert(io.open(strtofile, "wb"))
local data = inp:read("*all")
out:write(data)
assert(inp:close())
assert(out:close())
-- Copy the last modification date and access date from the original.
local attr = lfs.attributes(strfromfile)
lfs.touch(strtofile,attr['modification'],attr['access'])
return true
end
------------------------------------------------
-- DupDir
-- Makes a Directory and copies the modification date
-- @requires "LFS" module
------------------------------------------------
function DupDir(strfromDir,strtoDir)
local attr = lfs.attributes(strtoDir)
if attr == nil then -- Directory does not exist
lfs.mkdir(strtoDir)
end
end
------------------------------------------------
-- StartProgressBar
-- Progress Bar for long running Plugin.
------------------------------------------------
function StartProgressBar(strTitle)
cancelbutton = iup.button {
title = "Cancel",
size = "120x30",
action=function()
cancelflag = true
return iup.CLOSE
end
}
gaugeProgress = iup.progressbar{ expand="HORIZONTAL" }
dlgProgress = iup.dialog{
title = strTitle,
dialogframe = "YES", border = "YES",
iup.vbox {
gaugeProgress,
cancelbutton;
alignment = "ACENTER",gap=20
}
}
dlgProgress.size = "QUARTERxEIGHTH"
dlgProgress.menubox = "NO" -- Remove Windows close button and menu.
dlgProgress.close_cb = cancelbutton.action
dlgProgress:showxy(iup.CENTER, iup.CENTER) -- Put up Progress Display
end
----------------------------------------------------------------------------------
-- Main Code Starts Here
----------------------------------------------------------------------------------
-- Subfolders to copy as of Version 5
tblSubfolders = {
'Diagrams',
'Fact Types',
'Icons',
'Plugins',
'Property Box',
'Queries',
'Reports',
'Text Schemes'
}
-- Base Folder for Family Historian in Application Data
strAppDataFolder = fhGetContextInfo("CI_APP_DATA_FOLDER")..'\\'
-- Get Parms
parmFile = fhGetPluginDataFileName()
loadSettings,err = loadfile(parmFile)
if loadSettings == nil then
strDir = ''
else
loadSettings()
end
-- Creates a file dialog and sets its type, title, filter and filter info
filedlg = iup.filedlg{dialogtype = "DIR", title = "Export Custom items to Directory", directory = strDir}
-- Shows file dialog in the center of the screen
filedlg:popup (iup.ANYWHERE, iup.ANYWHERE)
-- Gets file dialog status
status = filedlg.status
if status == "0" then
-- Save Settings
if fhGetContextInfo('CI_APP_MODE') == 'Project Mode' then
local out = assert(io.open(parmFile, "w"))
out:write('strDir = "'..filedlg.value:gsub('\\','\\\\')..'"')
out:close()
end
StartProgressBar("File Copy in Progress, copying to "..filedlg.value)
strOutPutDir = filedlg.value .. '\\'
count = 0
for i,strDir in pairs(tblSubfolders) do
strLongDir = strAppDataFolder..strDir
DupDir(strLongDir,strOutPutDir..strDir)
gaugeProgress.value = gaugeProgress.value + .125
for strOrgItem, attr in dirtree(strLongDir) do
-- allow the dialog to process any messages
iup.LoopStep()
strNewItem = string.gsub(strOrgItem,strAppDataFolder,strOutPutDir)
ipos = string.find(strNewItem,'\\Standard\\')
if ipos == nil then -- Skip Contents of Standard Directories
if attr.mode == 'directory' then
DupDir(strOrgItem,strNewItem)
else
if attr.mode == 'file' then
CopyFile(strOrgItem,strNewItem,true)
count = count + 1
end
end
end
end
end
dlgProgress:destroy()
fhMessageBox('Backup Completed '..count..' files copied to '..strOutPutDir)
end
--[[
@Title: Backup Family Historian Settings
@Author: Jane Taubman
@LastUpdated: May 2012
@Version: 1.3
@Description: Creates a Backup of the Family Historian Settings to a backup location of your choice.
@changes:
1.1 Changed to use the Lua Path to find the FH Program Data folder so it works with XP.
1.1 Changed to simply return when No is selected on the first prompt.
1.2 Use the fhGetContextInfo("CI_APP_DATA_FOLDER") now it's been reinstated.
1.3 Don't save preferences when in Standalone Gedcom mode.
]]
require "iuplua" -- For directory dialog
require "lfs" -- To access the directory structure
------------------------------------------------
-- dirtree
-- Returns a directory tree.
------------------------------------------------
function dirtree(dir)
assert(dir and dir ~= "", "directory parameter is missing or empty")
if string.sub(dir, -1) == "/" then
dir=string.sub(dir, 1, -2)
end
local function yieldtree(dir)
for entry in lfs.dir(dir) do
if entry ~= "." and entry ~= ".." then
entry=dir.."\\"..entry
local attr=lfs.attributes(entry)
coroutine.yield(entry,attr)
if attr.mode == "directory" then
yieldtree(entry)
end
end
end
end
return coroutine.wrap(function() yieldtree(dir) end)
end
------------------------------------------------
-- file_exists
-- Checks if a file exists
------------------------------------------------
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true
else
return false
end
end
------------------------------------------------
-- CopyFile
-- Copies a file
-- @requires file_exists() function
-- @requires "LFS" module
-- @Parms strfromfile File to copy from
-- @Parms strtofile File to copy to
-- @Parms bReplace Boolean for existing to files true=replace file, false=skip
------------------------------------------------
function CopyFile(strfromfile,strtofile,bReplace)
if not(bReplace) then
if file_exists(strtofile) then
return false
end
end
local inp = assert(io.open(strfromfile, "rb"))
local out = assert(io.open(strtofile, "wb"))
local data = inp:read("*all")
out:write(data)
assert(inp:close())
assert(out:close())
-- Copy the last modification date and access date from the original.
local attr = lfs.attributes(strfromfile)
lfs.touch(strtofile,attr['modification'],attr['access'])
return true
end
------------------------------------------------
-- DupDir
-- Makes a Directory and copies the modification date
-- @requires "LFS" module
------------------------------------------------
function DupDir(strfromDir,strtoDir)
local attr = lfs.attributes(strtoDir)
if attr == nil then -- Directory does not exist
lfs.mkdir(strtoDir)
end
end
------------------------------------------------
-- StartProgressBar
-- Progress Bar for long running Plugin.
------------------------------------------------
function StartProgressBar(strTitle)
cancelbutton = iup.button {
title = "Cancel",
size = "120x30",
action=function()
cancelflag = true
return iup.CLOSE
end
}
gaugeProgress = iup.progressbar{ expand="HORIZONTAL" }
dlgProgress = iup.dialog{
title = strTitle,
dialogframe = "YES", border = "YES",
iup.vbox {
gaugeProgress,
cancelbutton;
alignment = "ACENTER",gap=20
}
}
dlgProgress.size = "QUARTERxEIGHTH"
dlgProgress.menubox = "NO" -- Remove Windows close button and menu.
dlgProgress.close_cb = cancelbutton.action
dlgProgress:showxy(iup.CENTER, iup.CENTER) -- Put up Progress Display
end
----------------------------------------------------------------------------------
-- Main Code Starts Here
----------------------------------------------------------------------------------
-- Subfolders to copy as of Version 5
tblSubfolders = {
'Diagrams',
'Fact Types',
'Icons',
'Plugins',
'Property Box',
'Queries',
'Reports',
'Text Schemes'
}
-- Base Folder for Family Historian in Application Data
strAppDataFolder = fhGetContextInfo("CI_APP_DATA_FOLDER")..'\\'
-- Get Parms
parmFile = fhGetPluginDataFileName()
loadSettings,err = loadfile(parmFile)
if loadSettings == nil then
strDir = ''
else
loadSettings()
end
-- Creates a file dialog and sets its type, title, filter and filter info
filedlg = iup.filedlg{dialogtype = "DIR", title = "Export Custom items to Directory", directory = strDir}
-- Shows file dialog in the center of the screen
filedlg:popup (iup.ANYWHERE, iup.ANYWHERE)
-- Gets file dialog status
status = filedlg.status
if status == "0" then
-- Save Settings
if fhGetContextInfo('CI_APP_MODE') == 'Project Mode' then
local out = assert(io.open(parmFile, "w"))
out:write('strDir = "'..filedlg.value:gsub('\\','\\\\')..'"')
out:close()
end
StartProgressBar("File Copy in Progress, copying to "..filedlg.value)
strOutPutDir = filedlg.value .. '\\'
count = 0
for i,strDir in pairs(tblSubfolders) do
strLongDir = strAppDataFolder..strDir
DupDir(strLongDir,strOutPutDir..strDir)
gaugeProgress.value = gaugeProgress.value + .125
for strOrgItem, attr in dirtree(strLongDir) do
-- allow the dialog to process any messages
iup.LoopStep()
strNewItem = string.gsub(strOrgItem,strAppDataFolder,strOutPutDir)
ipos = string.find(strNewItem,'\\Standard\\')
if ipos == nil then -- Skip Contents of Standard Directories
if attr.mode == 'directory' then
DupDir(strOrgItem,strNewItem)
else
if attr.mode == 'file' then
CopyFile(strOrgItem,strNewItem,true)
count = count + 1
end
end
end
end
end
dlgProgress:destroy()
fhMessageBox('Backup Completed '..count..' files copied to '..strOutPutDir)
end
Source:Backup-Family-Historian-Settings1.fh_lua