Module to get programmatic access to a Translator instance

I’ve been having a few chats with customers who are curious about exporting files from a Translator instance to various places like another fossil repository or another third party source code control system.

We have plans to support some of that built into Iguana but we’d also like to provide the ability for customers to extend the Iguana GUI itself using Lua.

So as a quick proof of concept I wrote a module which checks out the Fossil repository and returns a table object containing all the data for a Translator instance’s files.  It’s quite easy to do since the Translator is built on open standard based code.

This shows it’s usage pulling code a From Translator instance that has some code pulling a RSS feed from CNN:

Here is the code to copy:

-- NOTE: this code requires <your channel> to use a "From Translator" Source
--       if you use repo.TO <your channel> must use a "To Translator" Destination

local repo = require 'repo'

function main(Data)
   local A = repo.ExtractChannel(
      '<your channel name>', 'c:temp', repo.FROM)
   trace(A.main)
   trace(A.shared.node)
   local R = 'Shared modules:'
   for Shared in pairs(A.shared) do 
      R = R..', '..Shared
   end
   trace(R) 
end

It shows that with a little bit of creativity what is possible to do with the Translator using it to process Iguana’s own configuration files.  This code could be used as the basis of exporting the Translator code into another source code control system.

The third argument is the type of Translator instance:

Script Type Description
repo.FROM From Translator instance
repo.TO To Translator instance
repo.FILTER Filter Translator instance
repo.ACK Translator instance for handling ACKnowledgments in an LLP listener component

See documentation on the layout of the repository.

local repo = {}

local function Exec(Command) 
   local F = io.popen(Command)
   local R = F:read('*a')
   F:close()
   return R
end

local function ReadFile(FileName)
   local F = io.open(FileName)
   local X = F:read("*all")
   F:close()
   return X
end

local function WriteFile(FileName, Content)
   local F = io.open(FileName, "w") 
   F:write(Content)
   F:close()
end

local function GetSharedFile(FileName)
   return ReadFile('edit/admin/shared/'..FileName..'.lua')
end

local function GetOtherFile(FileName)
   return ReadFile('edit/admin/other/'..FileName)
end

function node.getChannel(C, Name) 
   for i=1,#C.iguana_config.channel_config do
      local Chan = C.iguana_config.channel_config[i]
      if Chan.name:nodeValue() == Name then
         return Chan
      end
   end
   return nil
end

function ExportFossil(TempDir, ExportDir)
   os.execute('cd "'..TempDir..'" & mkdir "'..ExportDir..'"')
   local A = Exec('cd')
   A = A:gsub('\n', '')
   A = A:gsub('/', '\\')
   os.execute('cd "'..TempDir..ExportDir..'\\" & "'..A..'\\fossil" open "'..A..'\\vcs_repo.sqlite"')
end

local function CleanFossil(TempDir, ExportDir)
   os.execute('rmdir /s /q '.. TempDir..ExportDir)
end

repo.FROM = 1
repo.TO = 2
repo.FILTER = 3 
repo.ACK = 4

function ScriptGuid(ScriptType, ChannelName, Config)
   if ScriptType == repo.TO then return Config:getChannel(ChannelName).to_mapper.guid:nodeValue() end
   if ScriptType == repo.FROM then return Config:getChannel(ChannelName).from_mapper.guid:nodeValue() end
   if ScriptType == repo.FILTER then return Config:getChannel(ChannelName).message_filter.translator_guid:nodeValue() end
   if ScriptType == repo.ACK then return Config:getChannel(ChannelName).llp_listener.ack_script:nodeValue() end
end

function repo.ExtractChannel(ChannelName, TempDir, ScriptType)
   if not ScriptType then ScriptType = repo.TO end
   local EDir = 'export'
   CleanFossil(TempDir, EDir)
   ExportFossil(TempDir, EDir)
   local Root = TempDir .. EDir..'\\'
   local X = ReadFile('IguanaConfiguration.xml')
   X = xml.parse{data=X}
   local Guid = ScriptGuid(ScriptType, ChannelName, X)
   local Result={shared={}, other={}}
   Result.main = ReadFile(Root..Guid..'\\main.lua')

   local Project = ReadFile(Root..Guid..'/project.prj')
   print(Project)
   Project=json.parse{data=Project}
   Result.project = Project
   print(Result.project.Name)
   for i=1,#Project.LuaDependencies do
      print(Project.LuaDependencies[i])
      local Code = GetSharedFile(Project.LuaDependencies[i])
      Result.shared[Project.LuaDependencies[i]] = Code
   end
   for i=1,#Project.OtherDependencies do
      print(Project.OtherDependencies[i])   
      local Code = GetOtherFile(Project.OtherDependencies[i])
      Result.other[Project.OtherDependencies[i]] = Code
   end 
   CleanFossil(TempDir, EDir)
   return Result
end

return repo