Created libraries from commonly used functions. Moved official/debug-helpers.lua into lib/dtutils/debug.lua. Created a logging library to provide various levels of logging. Documented all libraries and functions. Created tools to extract documentation in text, man page, and pdf formats.
This commit is contained in:
457
lib/dtutils.lua
Normal file
457
lib/dtutils.lua
Normal file
@@ -0,0 +1,457 @@
|
||||
--[[
|
||||
|
||||
dtutils.lua - common darktable lua functions
|
||||
|
||||
Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
Copyright (C) 2016 Tobias Jakobs
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
local dtutils = {}
|
||||
|
||||
dtutils.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "See_Also", "License"},
|
||||
Name = [[dtutils - A Darktable lua utilities library]],
|
||||
Synopsis = [[local du = require "lib/dtutils"]],
|
||||
Description = [[dtutils provides a common library of functions used to build
|
||||
lua scripts. There are also sublibraries that provide more functions.]],
|
||||
See_Also = [[dtutils.debug(3), dtutils.extensionts(3), dtutils.file(3), dtutils.processor(3)]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
local log = require "lib/libLog"
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
--[[
|
||||
NAME
|
||||
split - split a string on a specified separator
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.split(str, pat)
|
||||
str - string - the string to split
|
||||
pat - string - the pattern to split on
|
||||
|
||||
DESCRIPTION
|
||||
split separates a string into a table of strings. The strings are separated at each
|
||||
occurrence of the supplied pattern.
|
||||
|
||||
RETURN VALUE
|
||||
result - a table of strings on success, or an empty table on error
|
||||
|
||||
EXAMPLE
|
||||
split("/a/long/path/name/to/a/file.txt", "/") would return a table like
|
||||
{"a", "long", "path", "name", "to", "a", "file.txt"}
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Example"},
|
||||
Name = [[split - split a string on a specified separator]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.split(str, pat)
|
||||
str - string - the string to split
|
||||
pat - string - the pattern to split on]],
|
||||
Description = [[split separates a string into a table of strings. The strings are separated at each
|
||||
occurrence of the supplied pattern.]],
|
||||
Return_Value = [[result - a table of strings on success, or an empty table on error]],
|
||||
Example = [[split("/a/long/path/name/to/a/file.txt", "/") would return a table like
|
||||
{"a", "long", "path", "name", "to", "a", "file.txt"}]],
|
||||
}
|
||||
|
||||
-- Thanks to http://lua-users.org/wiki/SplitJoin
|
||||
function dtutils.split(str, pat)
|
||||
local t = {} -- NOTE: use {n = 0} in Lua-5.0
|
||||
local fpat = "(.-)" .. pat
|
||||
local last_end = 1
|
||||
local s, e, cap = str:find(fpat, 1)
|
||||
while s do
|
||||
if s ~= 1 or cap ~= "" then
|
||||
table.insert(t,cap)
|
||||
end
|
||||
last_end = e+1
|
||||
s, e, cap = str:find(fpat, last_end)
|
||||
end
|
||||
if last_end <= #str then
|
||||
cap = str:sub(last_end)
|
||||
table.insert(t, cap)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
join - join a table of strings with a specified separator
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.join(tabl, pat)
|
||||
tabl - a table of strings
|
||||
pat - a separator
|
||||
|
||||
DESCRIPTION
|
||||
join assembles a table of strings into a string with the specified pattern
|
||||
in between each string
|
||||
|
||||
RETURN VALUE
|
||||
result - the joined string on success, or an empty string on failure
|
||||
|
||||
EXAMPLE
|
||||
join({"a", "long", "path", "name", "to", "a", "file.txt"}, " ") would return the string
|
||||
"a long path name to a file.txt"
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Example"},
|
||||
Name = [[join - join a table of strings with a specified separator]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.join(tabl, pat)
|
||||
tabl - a table of strings
|
||||
pat - a separator]],
|
||||
Description = [[join assembles a table of strings into a string with the specified pattern
|
||||
in between each string]],
|
||||
Return_Value = [[result - the joined string on success, or an empty string on failure]],
|
||||
Example = [[join({"a", "long", "path", "name", "to", "a", "file.txt"}, " ") would return the string
|
||||
"a long path name to a file.txt"]],
|
||||
}
|
||||
|
||||
-- Thanks to http://lua-users.org/wiki/SplitJoin
|
||||
function dtutils.join(tabl, pat)
|
||||
returnstr = ""
|
||||
for i,str in pairs(tabl) do
|
||||
returnstr = returnstr .. str .. pat
|
||||
end
|
||||
return string.sub(returnstr, 1, -(pat:len() + 1))
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
prequire - a protected lua require
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.prequire(req_name)
|
||||
req_name - the filename of the lua code to load without the ".lua" filetype
|
||||
|
||||
DESCRIPTION
|
||||
prequire is a protected require that can survive an error in the code being loaded without
|
||||
bringing down the calling routine.
|
||||
|
||||
RETURN VALUE
|
||||
result - the code or true on success, otherwise an error message
|
||||
|
||||
EXAMPLE
|
||||
prequire("lib/dtutils.file") which would load lib/dtutils/file.lua
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Example"},
|
||||
Name = [[prequire - a protected lua require]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.prequire(req_name)
|
||||
req_name - the filename of the lua code to load without the ".lua" filetype]],
|
||||
Description = [[prequire is a protected require that can survive an error in the code being loaded without
|
||||
bringing down the calling routine.]],
|
||||
Return_Value = [[result - the code or true on success, otherwise an error message]],
|
||||
Example = [[prequire("lib/dtutils.file") which would load lib/dtutils/file.lua]],
|
||||
}
|
||||
|
||||
function dtutils.prequire(req_name)
|
||||
local status, lib = pcall(require, req_name)
|
||||
if status then
|
||||
log.msg(log.info, "Loaded " .. req_name)
|
||||
else
|
||||
log.msg(log.info, "Error loading " .. req_name)
|
||||
end
|
||||
return lib
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
push - push a value on a stack
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
du.push(stack, value)
|
||||
stack - table - a table being used as the stack
|
||||
value - any type - the value to be put on the stack
|
||||
|
||||
DESCRIPTION
|
||||
Push a value on a stack
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[push - push a value on a stack]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
du.push(stack, value)
|
||||
stack - table - a table being used as the stack
|
||||
value - any type - the value to be put on the stack]],
|
||||
Description = [[Push a value on a stack]],
|
||||
Return_Value = [[none]],
|
||||
}
|
||||
|
||||
dtutils.push = table.insert
|
||||
|
||||
--[[
|
||||
NAME
|
||||
pop - pop a value from a stack
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.pop(stack)
|
||||
stack - table - a table being used as a stack
|
||||
|
||||
DESCRIPTION
|
||||
Remove the last value pushed on the stack and return it
|
||||
|
||||
RETURN VALUE
|
||||
result = nil if stack isn't a table or the stack is empty, otherwise the value removed from the stack
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[pop - pop a value from a stack]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.pop(stack)
|
||||
stack - table - a table being used as a stack]],
|
||||
Description = [[Remove the last value pushed on the stack and return it]],
|
||||
Return_Value = [[result = nil if stack isn't a table or the stack is empty, otherwise the value removed from the stack]],
|
||||
}
|
||||
|
||||
dtutils.pop = table.remove
|
||||
|
||||
--[[
|
||||
NAME
|
||||
update_combobox_choices - change the list of choices in a combobox
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
du.update_combobox_choices(combobox_widget, choice_table)
|
||||
combobox_widget - lua_combobox - a combobox widget
|
||||
choice_table - table - a table of strings for the combobox choices
|
||||
|
||||
DESCRIPTION
|
||||
Set the combobox choices to the supplied list. Remove any extra choices from the end
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[update_combobox_choices - change the list of choices in a combobox]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
du.update_combobox_choices(combobox_widget, choice_table)
|
||||
combobox_widget - lua_combobox - a combobox widget
|
||||
choice_table - table - a table of strings for the combobox choices]],
|
||||
Description = [[Set the combobox choices to the supplied list. Remove any extra choices from the end]],
|
||||
Return_Value = [[none]],
|
||||
}
|
||||
|
||||
function dtutils.update_combobox_choices(combobox, choice_table)
|
||||
local items = #combobox
|
||||
local choices = #choice_table
|
||||
for i, name in ipairs(choice_table) do
|
||||
log.msg(log.debug, "Setting choice " .. i .. " to " .. name)
|
||||
combobox[i] = name
|
||||
end
|
||||
if choices < items then
|
||||
for j = items, choices + 1, -1 do
|
||||
log.msg(log.debug, "Removing choice " .. j)
|
||||
combobox[j] = nil
|
||||
end
|
||||
end
|
||||
combobox.value = 1
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
spairs - an iterator that provides sorted pairs from a table
|
||||
|
||||
SYNOPSIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
for key, value in du.spairs(t, order) do
|
||||
t - table - table of key, value pairs
|
||||
order - function - an optional function to sort the pairs
|
||||
if none is supplied, table.sort() is used
|
||||
|
||||
DESCIRPTION
|
||||
spairs is an iterator that returns key, value pairs from a table in sorted
|
||||
order. The sorting order is the result of table.sort() if no function is
|
||||
supplied, otherwise sorting is done as specified in the function.
|
||||
|
||||
EXAMPLE
|
||||
HighScore = { Robin = 8, Jon = 10, Max = 11 }
|
||||
|
||||
-- basic usage, just sort by the keys
|
||||
for k,v in spairs(HighScore) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Jon 10
|
||||
--> Max 11
|
||||
--> Robin 8
|
||||
|
||||
-- this uses an custom sorting function ordering by score descending
|
||||
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Max 11
|
||||
--> Jon 10
|
||||
--> Robin 8
|
||||
|
||||
REFERENCE
|
||||
Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Example", "Reference"},
|
||||
Name = [[spairs - an iterator that provides sorted pairs from a table]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
for key, value in du.spairs(t, order) do
|
||||
t - table - table of key, value pairs
|
||||
order - function - an optional function to sort the pairs
|
||||
if none is supplied, table.sort() is used]],
|
||||
Description = [[spairs is an iterator that returns key, value pairs from a table in sorted
|
||||
order. The sorting order is the result of table.sort() if no function is
|
||||
supplied, otherwise sorting is done as specified in the function.]],
|
||||
Example = [[HighScore = { Robin = 8, Jon = 10, Max = 11 }
|
||||
|
||||
-- basic usage, just sort by the keys
|
||||
for k,v in spairs(HighScore) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Jon 10
|
||||
--> Max 11
|
||||
--> Robin 8
|
||||
|
||||
-- this uses an custom sorting function ordering by score descending
|
||||
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
|
||||
print(k,v)
|
||||
end
|
||||
--> Max 11
|
||||
--> Jon 10
|
||||
--> Robin 8]],
|
||||
Reference = [[Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua]],
|
||||
}
|
||||
|
||||
-- Sort a table
|
||||
function dtutils.spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
for _key in pairs(_table) do keys[#keys + 1] = _key end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a,b) return order(_table, a, b) end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], _table[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
|
||||
NAME
|
||||
urlencode - encode a string in a websage manner
|
||||
|
||||
SYNOPOIS
|
||||
local du = require "lib/dtutils"
|
||||
|
||||
local result = du.urlencode(str)
|
||||
str - string - the string that needs to be made websafe
|
||||
|
||||
DESCRIPTION
|
||||
urlencode converts a string into a websafe version suitable for
|
||||
use in a web browser.
|
||||
|
||||
RETURN_VALUE
|
||||
result - string - a websafe string
|
||||
|
||||
REFERENCE
|
||||
https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/
|
||||
|
||||
]]
|
||||
|
||||
dtutils.libdoc.functions[#dtutils.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Reference"},
|
||||
Name = [[urlencode - encode a string in a websage manner]],
|
||||
Synopsis = [[local du = require "lib/dtutils"
|
||||
|
||||
local result = du.urlencode(str)
|
||||
str - string - the string that needs to be made websafe]],
|
||||
Description = [[urlencode converts a string into a websafe version suitable for
|
||||
use in a web browser.]],
|
||||
Return_Value = [[result - string - a websafe string]],
|
||||
Reference = [[https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/]],
|
||||
}
|
||||
|
||||
function dtutils.urlencode(str)
|
||||
if (str) then
|
||||
str = string.gsub (str, "\n", "\r\n")
|
||||
str = string.gsub (str, "([^%w ])", function () return string.format ("%%%02X", string.byte()) end)
|
||||
str = string.gsub (str, " ", "+")
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
return dtutils
|
||||
23
lib/dtutils/de_DE/LC_MESSAGES/dtutils.processor.po
Normal file
23
lib/dtutils/de_DE/LC_MESSAGES/dtutils.processor.po
Normal file
@@ -0,0 +1,23 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-10-01 00:36-0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: dtutils.processor.lua:42
|
||||
#, lua-format
|
||||
msgid "Export Image %i/%i"
|
||||
msgstr "Exportiere Bild %i/%i"
|
||||
219
lib/dtutils/debug.lua
Normal file
219
lib/dtutils/debug.lua
Normal file
@@ -0,0 +1,219 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2014 Jérémy Rosen
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
DEBUG HELPERS
|
||||
A collection of helper functions to help debugging lua scripts.
|
||||
|
||||
require it as
|
||||
|
||||
dhelpers = require "official/debug-helpers"
|
||||
|
||||
Each function is documented in its own header
|
||||
|
||||
|
||||
]]
|
||||
|
||||
|
||||
local dt = require "darktable"
|
||||
local io = require "io"
|
||||
local table = require "table"
|
||||
require "darktable.debug"
|
||||
local log = require "lib/libLog"
|
||||
local M = {} -- The actual content of the module
|
||||
|
||||
M.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "License"},
|
||||
Name = [[dtutils.debug - debugging helpers used in developing darktable lua scripts]],
|
||||
Synopsis = [[local dd = require "lib/dtutils.debug"]],
|
||||
Description = [[dtutils.debug provides an interface to the darktable debugging routines.]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
tracepoint - print out a tracepoint and dump the arguments
|
||||
|
||||
SYNOPSIS
|
||||
local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of
|
||||
|
||||
DESCRIPTION
|
||||
tracepoint prints its name and dumps its parameters using
|
||||
dt.debug
|
||||
|
||||
RETURN VALUE
|
||||
result - ... - the supplied argument list
|
||||
|
||||
]]
|
||||
|
||||
M.libdoc.functions[#M.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[tracepoint - print out a tracepoint and dump the arguments]],
|
||||
Synopsis = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of]],
|
||||
Description = [[tracepoint prints its name and dumps its parameters using
|
||||
dt.debug]],
|
||||
Return_Value = [[result - ... - the supplied argument list]],
|
||||
}
|
||||
|
||||
function M.tracepoint(name,...)
|
||||
log.always(4, "***** "..name.." ****")
|
||||
params = {...}
|
||||
print(dt.debug.dump(params,"parameters"))
|
||||
return ...;
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
NAME
|
||||
new_tracepoint - create a function returning a tracepoint
|
||||
|
||||
SYNOPSIS
|
||||
local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = new_tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
A function that returns a tracepoint function with the given name
|
||||
This is mainly used to debug callbacks.
|
||||
|
||||
RETURN VALUE
|
||||
result - function - a function that returns the result of a tracepoint
|
||||
|
||||
EXAMPLE
|
||||
register_event(event, dd.new_tracepoint("hit callback"))
|
||||
|
||||
will print the following each time the callback is called
|
||||
|
||||
**** hit callback ****
|
||||
<all the callback's parameters dumped>
|
||||
|
||||
]]
|
||||
|
||||
M.libdoc.functions[#M.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Example"},
|
||||
Name = [[new_tracepoint - create a function returning a tracepoint]],
|
||||
Synopsis = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
local result = new_tracepoint(name, ...)
|
||||
name - string - the name of the tracepoint to print out
|
||||
... - arguments - variables to dump the contents of]],
|
||||
Description = [[A function that returns a tracepoint function with the given name
|
||||
This is mainly used to debug callbacks.]],
|
||||
Return_Value = [[result - function - a function that returns the result of a tracepoint]],
|
||||
Example = [[register_event(event, dd.new_tracepoint("hit callback"))
|
||||
|
||||
will print the following each time the callback is called
|
||||
|
||||
**** hit callback ****
|
||||
<all the callback's parameters dumped>]],
|
||||
}
|
||||
|
||||
function M.new_tracepoint(name)
|
||||
return function(...) return M.tracepoint(name,...) end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
NAME
|
||||
dprint - pass a variable to dt.debug.dump and print the results to stdout
|
||||
|
||||
SYNOPSIS
|
||||
local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.dprint(var)
|
||||
var - variable - any variable that you want to see the contents of
|
||||
|
||||
DESCRIPTION
|
||||
Wrapper around debug.dump, will directly print to stdout,
|
||||
same calling convention
|
||||
|
||||
]]
|
||||
|
||||
M.libdoc.functions[#M.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description"},
|
||||
Name = [[dprint - pass a variable to dt.debug.dump and print the results to stdout]],
|
||||
Synopsis = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.dprint(var)
|
||||
var - variable - any variable that you want to see the contents of]],
|
||||
Description = [[Wrapper around debug.dump, will directly print to stdout,
|
||||
same calling convention]],
|
||||
}
|
||||
|
||||
function M.dprint(...)
|
||||
log.always(4, dt.debug.dump(...))
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
terse_dump - set dt.debug.known to shorten all image dumps to a single line
|
||||
|
||||
SYNOPSIS
|
||||
local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.terse_dump()
|
||||
|
||||
DESCRIPTION
|
||||
terse_dump sets dt.debug.known to shorten all images to a single line.
|
||||
If you don't need to debug the content of images, this will avoid them flooding your logs
|
||||
]]
|
||||
|
||||
M.libdoc.functions[#M.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description"},
|
||||
Name = [[terse_dump - set dt.debug.known to shorten all image dumps to a single line]],
|
||||
Synopsis = [[local dd = require "lib/dtutils.debug"
|
||||
|
||||
dd.terse_dump()]],
|
||||
Description = [[terse_dump sets dt.debug.known to shorten all images to a single line.
|
||||
If you don't need to debug the content of images, this will avoid them flooding your logs]],
|
||||
}
|
||||
|
||||
function M.terse_dump()
|
||||
for _,v in ipairs(dt.database) do
|
||||
dt.debug.known[v] = tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
185
lib/dtutils/extensions.lua
Normal file
185
lib/dtutils/extensions.lua
Normal file
@@ -0,0 +1,185 @@
|
||||
--[[
|
||||
|
||||
NAME
|
||||
dtutils/extensions.lua - a library of extenstions to the lua libraries
|
||||
|
||||
SYNOPSIS
|
||||
require "lib/dtutils.extensions"
|
||||
|
||||
DESCRIPTION
|
||||
This library contains extensions to the lua libraries.
|
||||
|
||||
]]
|
||||
|
||||
local dtutils_extensions = {}
|
||||
dtutils_extensions.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "License"},
|
||||
Name = "dtutils.extensions - a library of extenstions to the lua libraries",
|
||||
Synopsis = [[require "lib/dtutils.extensions"]],
|
||||
Description = [[This library contains extensions to the lua libraries.]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
--[[
|
||||
|
||||
NAME
|
||||
string.strip_accents - strip accents from characters
|
||||
|
||||
SYNOPSIS
|
||||
require "lib/dtutils.extensions"
|
||||
|
||||
result = string.strip_accents(str)
|
||||
str - string - the string with characters that need accents removed
|
||||
|
||||
DESCRIPTION
|
||||
strip_accents removes accents from accented characters returning the
|
||||
unaccented character.
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the string containing unaccented characters
|
||||
|
||||
]]
|
||||
|
||||
dtutils_extensions.libdoc.functions[#dtutils_extensions.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[string.strip_accents - strip accents from characters]],
|
||||
Synopsis = [[require "lib/dtutils.extensions"
|
||||
|
||||
result = string.strip_accents(str)
|
||||
str - string - the string with characters that need accents removed]],
|
||||
Description = [[strip_accents removes accents from accented characters returning the
|
||||
unaccented character.]],
|
||||
Return_Value = [[result - string - the string containing unaccented characters]],
|
||||
}
|
||||
|
||||
-- Strip accents from a string
|
||||
-- Copied from https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/
|
||||
function string.strip_accents( str )
|
||||
local tableAccents = {}
|
||||
tableAccents["à"] = "a"
|
||||
tableAccents["á"] = "a"
|
||||
tableAccents["â"] = "a"
|
||||
tableAccents["ã"] = "a"
|
||||
tableAccents["ä"] = "a"
|
||||
tableAccents["ç"] = "c"
|
||||
tableAccents["è"] = "e"
|
||||
tableAccents["é"] = "e"
|
||||
tableAccents["ê"] = "e"
|
||||
tableAccents["ë"] = "e"
|
||||
tableAccents["ì"] = "i"
|
||||
tableAccents["í"] = "i"
|
||||
tableAccents["î"] = "i"
|
||||
tableAccents["ï"] = "i"
|
||||
tableAccents["ñ"] = "n"
|
||||
tableAccents["ò"] = "o"
|
||||
tableAccents["ó"] = "o"
|
||||
tableAccents["ô"] = "o"
|
||||
tableAccents["õ"] = "o"
|
||||
tableAccents["ö"] = "o"
|
||||
tableAccents["ù"] = "u"
|
||||
tableAccents["ú"] = "u"
|
||||
tableAccents["û"] = "u"
|
||||
tableAccents["ü"] = "u"
|
||||
tableAccents["ý"] = "y"
|
||||
tableAccents["ÿ"] = "y"
|
||||
tableAccents["À"] = "A"
|
||||
tableAccents["Á"] = "A"
|
||||
tableAccents["Â"] = "A"
|
||||
tableAccents["Ã"] = "A"
|
||||
tableAccents["Ä"] = "A"
|
||||
tableAccents["Ç"] = "C"
|
||||
tableAccents["È"] = "E"
|
||||
tableAccents["É"] = "E"
|
||||
tableAccents["Ê"] = "E"
|
||||
tableAccents["Ë"] = "E"
|
||||
tableAccents["Ì"] = "I"
|
||||
tableAccents["Í"] = "I"
|
||||
tableAccents["Î"] = "I"
|
||||
tableAccents["Ï"] = "I"
|
||||
tableAccents["Ñ"] = "N"
|
||||
tableAccents["Ò"] = "O"
|
||||
tableAccents["Ó"] = "O"
|
||||
tableAccents["Ô"] = "O"
|
||||
tableAccents["Õ"] = "O"
|
||||
tableAccents["Ö"] = "O"
|
||||
tableAccents["Ù"] = "U"
|
||||
tableAccents["Ú"] = "U"
|
||||
tableAccents["Û"] = "U"
|
||||
tableAccents["Ü"] = "U"
|
||||
tableAccents["Ý"] = "Y"
|
||||
|
||||
local normalizedString = ""
|
||||
|
||||
for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do
|
||||
if tableAccents[strChar] ~= nil then
|
||||
normalizedString = normalizedString..tableAccents[strChar]
|
||||
else
|
||||
normalizedString = normalizedString..strChar
|
||||
end
|
||||
end
|
||||
|
||||
return normalizedString
|
||||
|
||||
end
|
||||
|
||||
--[[
|
||||
|
||||
NAME
|
||||
string.escape_xml_characters - escape characters for xml documents
|
||||
|
||||
SYNOPSIS
|
||||
require "lib/dtutils.extensions"
|
||||
|
||||
result = string.escape_xml_characters(str)
|
||||
str - string - the string that needs escaped
|
||||
|
||||
DESCRIPTION
|
||||
escape_xml_characters provides the escape sequences for
|
||||
"&", '"', "'", "<", and ">" with the corresponding "&",
|
||||
""", "'", "<", and ">".
|
||||
|
||||
RETURNN VALUE
|
||||
result - string - the string containing escapes for the xml characters
|
||||
|
||||
]]
|
||||
|
||||
dtutils_extensions.libdoc.functions[#dtutils_extensions.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = "string.escape_xml_characters - escape characters for xml documents",
|
||||
Synopsis = [[ require "lib/dtutils.extensions"
|
||||
|
||||
result = string.escape_xml_characters(str)
|
||||
str - string - the string that needs escaped]],
|
||||
Description = [[escape_xml_characters provides the escape sequences for
|
||||
"&", '"', "'", "<", and ">" with the corresponding "&",
|
||||
""", "'", "<", and ">".]],
|
||||
Return_Value = [[result - string - the string containing escapes for the xml characters]],
|
||||
}
|
||||
|
||||
-- Escape XML characters
|
||||
-- Keep & first, otherwise it will double escape other characters
|
||||
-- https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents
|
||||
function string.escape_xml_characters( str )
|
||||
|
||||
str = string.gsub(str,"&", "&")
|
||||
str = string.gsub(str,"\"", """)
|
||||
str = string.gsub(str,"'", "'")
|
||||
str = string.gsub(str,"<", "<")
|
||||
str = string.gsub(str,">", ">")
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
return dtutils_extensions
|
||||
523
lib/dtutils/file.lua
Normal file
523
lib/dtutils/file.lua
Normal file
@@ -0,0 +1,523 @@
|
||||
--[[
|
||||
|
||||
dtutils/file.lua - common darktable lua file functions
|
||||
|
||||
Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
Copyright (C) 2016 Tobias Jakobs
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
local dtutils_file = {}
|
||||
dtutils_file.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "License"},
|
||||
Name = [[dtutils.file - common darktable lua file functions]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"]],
|
||||
Description = [[dtutils.file provides common file manipulation functions used in
|
||||
constructing Darktable lua scripts]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
local log = require "lib/libLog"
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("dtutils.file",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("dtutils.file", msgid)
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
check_if_bin_exists - check if an executable is in the path
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_bin_exists(bin)
|
||||
bin - string - the binary to check for
|
||||
|
||||
DESCRIPTION
|
||||
check_if_bin_exists checks to see if the specified binary executable is
|
||||
in the path.
|
||||
|
||||
RETURN VALUE
|
||||
result - boolean - true if the executable was found, false if not
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[check_if_bin_exists - check if an executable is in the path]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_bin_exists(bin)
|
||||
bin - string - the binary to check for]],
|
||||
Description = [[check_if_bin_exists checks to see if the specified binary executable is
|
||||
in the path.]],
|
||||
Return_Value = [[result - boolean - true if the executable was found, false if not]],
|
||||
}
|
||||
|
||||
function dtutils_file.check_if_bin_exists(bin)
|
||||
local result = os.execute("which " .. bin)
|
||||
if not result then
|
||||
result = false
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
split_filepath - split a filepath into parts
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.split_filepath(filepath)
|
||||
filepath - string - path and filename
|
||||
|
||||
DESCRIPTION
|
||||
split_filepath splits a filepath into the path, filename, basename and filetype and puts
|
||||
that in a table
|
||||
|
||||
RETURN VALUE
|
||||
result - table - a table containing the path, filename, basename, and filetype
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[split_filepath - split a filepath into parts]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.split_filepath(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[split_filepath splits a filepath into the path, filename, basename and filetype and puts
|
||||
that in a table]],
|
||||
Return_Value = [[result - table - a table containing the path, filename, basename, and filetype]],
|
||||
}
|
||||
|
||||
function dtutils_file.split_filepath(str)
|
||||
local result = {}
|
||||
-- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little
|
||||
result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
get_path - get the path from a file path
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_path(filepath)
|
||||
filepath - string - path and filename
|
||||
|
||||
DESCRIPTION
|
||||
get_path strips the filename and filetype from a path and returns the path
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the path
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[get_path - get the path from a file path]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_path(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_path strips the filename and filetype from a path and returns the path]],
|
||||
Return_Value = [[result - string - the path]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_path(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["path"]
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
get_filename - get the filename and extension from a file path
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filename(filepath)
|
||||
filepath - string - path and filename
|
||||
|
||||
DESCRIPTION
|
||||
get_filename strips the path from a filepath and returns the filename
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the file name and type
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[get_filename - get the filename and extension from a file path]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filename(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_filename strips the path from a filepath and returns the filename]],
|
||||
Return_Value = [[result - string - the file name and type]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_filename(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["filename"]
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
get_basename - get the filename without the path or extension
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_basename(filepath)
|
||||
filepath - string - path and filename
|
||||
|
||||
DESCRIPTION
|
||||
get_basename returns the name of the file without the path or filetype
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the basename of the file
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[get_basename - get the filename without the path or extension]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_basename(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_basename returns the name of the file without the path or filetype]],
|
||||
Return_Value = [[result - string - the basename of the file]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_basename(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["basename"]
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
get_filetype - get the filetype from a filename
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filetype(filepath)
|
||||
filepath - string - path and filename
|
||||
|
||||
DESCRIPTION
|
||||
get_filetype returns the filetype from the supplied filepath
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the filetype
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[get_filetype - get the filetype from a filename]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.get_filetype(filepath)
|
||||
filepath - string - path and filename]],
|
||||
Description = [[get_filetype returns the filetype from the supplied filepath]],
|
||||
Return_Value = [[result - string - the filetype]],
|
||||
}
|
||||
|
||||
function dtutils_file.get_filetype(str)
|
||||
local parts = dtutils_file.split_filepath(str)
|
||||
return parts["filetype"]
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
check_if_file_exists - check if a file or path exist
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_file_exists(filepath)
|
||||
filepath - string - a file or path to check
|
||||
|
||||
DESCRIPTION
|
||||
check_if_file_exists checks to see if a file or path exists
|
||||
|
||||
RETURN VALUE
|
||||
result - boolean - true if the file or path exists, false if it doesn't
|
||||
|
||||
]]
|
||||
|
||||
-- Thanks Tobias Jakobs for the idea
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[check_if_file_exists - check if a file or path exist]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.check_if_file_exists(filepath)
|
||||
filepath - string - a file or path to check]],
|
||||
Description = [[check_if_file_exists checks to see if a file or path exists]],
|
||||
Return_Value = [[result - boolean - true if the file or path exists, false if it doesn't]],
|
||||
}
|
||||
|
||||
function dtutils_file.check_if_file_exists(filepath)
|
||||
local result = os.execute("test -e " .. filepath)
|
||||
if not result then
|
||||
result = false
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
chop_filetype - remove a filetype from a filename
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.chop_filetype(path)
|
||||
path - string - a filename with or without a path
|
||||
|
||||
DESCRIPTION
|
||||
chop_filetype removes the filetype from the filename
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the path and filename without the filetype
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[chop_filetype - remove a filetype from a filename]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.chop_filetype(path)
|
||||
path - string - a filename with or without a path]],
|
||||
Description = [[chop_filetype removes the filetype from the filename]],
|
||||
Return_Value = [[result - string - the path and filename without the filetype]],
|
||||
}
|
||||
|
||||
function dtutils_file.chop_filetype(path)
|
||||
local length = dtutils_file.get_filetype(path):len() + 2
|
||||
return string.sub(path, 1, -length)
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
file_copy - copy a file to another name/location
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_copy(fromFile, toFile)
|
||||
fromFile - string - name of file to copy from
|
||||
toFile - string - name of file to copy to
|
||||
|
||||
DESCRIPTION
|
||||
copy a file using a succession of methods from operating system
|
||||
to a pure lua solution
|
||||
|
||||
RETURN VALUE
|
||||
result - boolean - nil on error, true on success
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[file_copy - copy a file to another name/location]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_copy(fromFile, toFile)
|
||||
fromFile - string - name of file to copy from
|
||||
toFile - string - name of file to copy to]],
|
||||
Description = [[copy a file using a succession of methods from operating system
|
||||
to a pure lua solution]],
|
||||
Return_Value = [[result - boolean - nil on error, true on success]],
|
||||
}
|
||||
|
||||
function dtutils_file.file_copy(fromFile, toFile)
|
||||
local result = nil
|
||||
-- if cp exists, use it
|
||||
if dtutils_file.check_if_bin_exists("cp") then
|
||||
result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
-- if cp was not present, or if cp failed, then a pure lua solution
|
||||
if not result then
|
||||
local fileIn, err = io.open(fromFile, 'rb')
|
||||
if fileIn then
|
||||
local fileOut, errr = io.open(toFile, 'w')
|
||||
if fileOut then
|
||||
local content = fileIn:read(4096)
|
||||
while content do
|
||||
fileOut:write(content)
|
||||
content = fileIn:read(4096)
|
||||
end
|
||||
result = true
|
||||
fileIn:close()
|
||||
fileOut:close()
|
||||
else
|
||||
log.msg(log.error, errr)
|
||||
end
|
||||
else
|
||||
log.msg(log.error, err)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
file_move - move a file from one directory to another
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_move(fromFile, toFile)
|
||||
fromFile - string - name of the original file
|
||||
toFile - string - the new file location and name
|
||||
|
||||
DESCRIPTION
|
||||
Move a file from one place to another. Try a succession of methods from
|
||||
builtin to operating system to a pure lua solution.
|
||||
|
||||
RETURN VALUE
|
||||
result - boolean - nil on error, some value on success
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[file_move - move a file from one directory to another]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.file_move(fromFile, toFile)
|
||||
fromFile - string - name of the original file
|
||||
toFile - string - the new file location and name]],
|
||||
Description = [[Move a file from one place to another. Try a succession of methods from
|
||||
builtin to operating system to a pure lua solution.]],
|
||||
Return_Value = [[result - boolean - nil on error, some value on success]],
|
||||
}
|
||||
|
||||
function dtutils_file.file_move(fromFile, toFile)
|
||||
local success = os.rename(fromFile, toFile)
|
||||
if not success then
|
||||
-- an error occurred, so let's try using the operating system function
|
||||
if dtutils_file.check_if_bin_exists("mv") then
|
||||
success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
-- if the mv didn't exist or succeed, then...
|
||||
if not success then
|
||||
-- pure lua solution
|
||||
success = dtutils_file.file_copy(fromFile, toFile)
|
||||
if success then
|
||||
os.remove(fromFile)
|
||||
else
|
||||
log.msg(log.error, "Unable to move " .. fromFile .. " to " .. toFile .. ". Leaving " .. fromFile .. " in place.")
|
||||
end
|
||||
end
|
||||
end
|
||||
return success -- nil on error, some value if success
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
filename_increment - add a two digit increment to a filename
|
||||
|
||||
SYNOPSIS
|
||||
local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.filename_increment(filepath)
|
||||
filepath - string - filename to increment
|
||||
|
||||
DESCRIPTION
|
||||
filename_increment solves the problem of filename confllict by adding an
|
||||
increment to the filename. If the supplied filename has no increment then
|
||||
"01" is added to the basename. If the filename already has an increment, then
|
||||
1 is added to it and the filename returned.
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the incremented filename
|
||||
|
||||
]]
|
||||
|
||||
dtutils_file.libdoc.functions[#dtutils_file.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[filename_increment - add a two digit increment to a filename]],
|
||||
Synopsis = [[local df = require "lib/dtutils.file"
|
||||
|
||||
local result = df.filename_increment(filepath)
|
||||
filepath - string - filename to increment]],
|
||||
Description = [[filename_increment solves the problem of filename confllict by adding an
|
||||
increment to the filename. If the supplied filename has no increment then
|
||||
"01" is added to the basename. If the filename already has an increment, then
|
||||
1 is added to it and the filename returned.]],
|
||||
Return_Value = [[result - string - the incremented filename]],
|
||||
}
|
||||
|
||||
function dtutils_file.filename_increment(filepath)
|
||||
|
||||
-- break up the filepath into parts
|
||||
local path = dtutils_file.get_path(filepath)
|
||||
local basename = dtutils_file.get_basename(filepath)
|
||||
local filetype = dtutils_file.get_filetype(filepath)
|
||||
|
||||
-- check to see if we've incremented before
|
||||
local increment = string.match(basename, "_(%d-)$")
|
||||
|
||||
if increment then
|
||||
-- we do 2 digit increments so make sure we didn't grab part of the filename
|
||||
if string.len(increment) > 2 then
|
||||
-- we got the filename so set the increment to 01
|
||||
increment = "01"
|
||||
else
|
||||
increment = string.format("%02d", tonumber(increment) + 1)
|
||||
basename = string.gsub(basename, "_(%d-)$", "")
|
||||
end
|
||||
else
|
||||
increment = "01"
|
||||
end
|
||||
local incremented_filepath = path .. basename .. "_" .. increment .. "." .. filetype
|
||||
|
||||
return incremented_filepath
|
||||
end
|
||||
|
||||
return dtutils_file
|
||||
266
lib/dtutils/processor.lua
Normal file
266
lib/dtutils/processor.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2016 Bill Ferguson
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
local dtutils_processor = {}
|
||||
|
||||
dtutils_processor.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "License"},
|
||||
Name = [[dtutils.processor - Darktable lua functions for building processor scripts]],
|
||||
Synopsis = [[local dp = require "lib/dtutils.processor"]],
|
||||
Description = [[dtutils.processor provides common functions used for building scripts
|
||||
that send images out to an external process, process them, and return the result (i.e. processors).]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
local dtutils = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local log = require "lib/libLog"
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
-- This should be $HOME/.config/darktable/lua/locale/
|
||||
gettext.bindtextdomain("dtutils",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("dtutils.processor", msgid)
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
exporter_status - show the status while exporting images
|
||||
|
||||
SYNOPSIS
|
||||
local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dp.exporter_status(storage, image, format, filename, number, total, high_quality, extra_data)
|
||||
storage - dt_imageio_module_storage_t - the storage that the status is being shown for
|
||||
image - dt_lua_image_t - the current image
|
||||
format - dt_imageio_module_format_t - the format of the export image
|
||||
filename - string - the filename being exported to
|
||||
number - integer - the number of this image in the sequence
|
||||
total - integer - the total number of images being exported
|
||||
high_quality - boolean
|
||||
extra_data - extra data from the storage
|
||||
|
||||
DESCRIPTION
|
||||
exporter_status runs prior to each image being exported and prints out a status that lets the user
|
||||
know how many images, out of the total, have been exported
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
]]
|
||||
|
||||
dtutils_processor.libdoc.functions[#dtutils_processor.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[exporter_status - show the status while exporting images]],
|
||||
Synopsis = [[local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dp.exporter_status(storage, image, format, filename, number, total, high_quality, extra_data)
|
||||
storage - dt_imageio_module_storage_t - the storage that the status is being shown for
|
||||
image - dt_lua_image_t - the current image
|
||||
format - dt_imageio_module_format_t - the format of the export image
|
||||
filename - string - the filename being exported to
|
||||
number - integer - the number of this image in the sequence
|
||||
total - integer - the total number of images being exported
|
||||
high_quality - boolean
|
||||
extra_data - extra data from the storage]],
|
||||
Description = [[exporter_status runs prior to each image being exported and prints out a status that lets the user
|
||||
know how many images, out of the total, have been exported]],
|
||||
Return_Value = [[none]],
|
||||
}
|
||||
|
||||
function dtutils_processor.exporter_status(storage, image, format, filename,
|
||||
number, total, high_quality, extra_data)
|
||||
dt.print(string.format(_("Export Image %i/%i"), number, total))
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
extract_image_list - assemble the exported image filenames from an image_table into a string
|
||||
|
||||
SYNOPSIS
|
||||
local dp = require "lib/dtutils.processor"
|
||||
|
||||
result = dp.extract_image_list(image_table)
|
||||
image_table - table - a table of images such as supplied by the exporter or by libPlugin.build_image_table
|
||||
|
||||
DESCRIPTION
|
||||
extract_image_list concatenates the exported image names into a space separated string suitable for
|
||||
passing as an argument to a processor. Each filename is bracketed with single quotes to protect against
|
||||
spaces and special characters in the filepath
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the assembled image list on success, or an empty image list on error
|
||||
|
||||
]]
|
||||
|
||||
dtutils_processor.libdoc.functions[#dtutils_processor.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[extract_image_list - assemble the exported image filenames from an image_table into a string]],
|
||||
Synopsis = [[local dp = require "lib/dtutils.processor"
|
||||
|
||||
result = dp.extract_image_list(image_table)
|
||||
image_table - table - a table of images such as supplied by the exporter or by libPlugin.build_image_table]],
|
||||
Description = [[extract_image_list concatenates the exported image names into a space separated string suitable for
|
||||
passing as an argument to a processor. Each filename is bracketed with single quotes to protect against
|
||||
spaces and special characters in the filepath]],
|
||||
Return_Value = [[result - string - the assembled image list on success, or an empty image list on error]],
|
||||
}
|
||||
|
||||
function dtutils_processor.extract_image_list(image_table)
|
||||
local img_list = ""
|
||||
for _,exp_img in pairs(image_table) do
|
||||
img_list = img_list .. " " .. "'" .. exp_img .. "'"
|
||||
end
|
||||
return img_list
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
extract_collection_path - extract the collection path from an image table
|
||||
|
||||
SYNOPSIS
|
||||
local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dp.extract_collection_path(image_table)
|
||||
image_table - table - a table of images such as supplied by the exporter or by libPlugin.build_image_table
|
||||
|
||||
DESCRIPTION
|
||||
extract_collection_path looks at the first image in the image_table and returns the path
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the collection path on success, or nil if there was an error
|
||||
|
||||
LIMITATIONS
|
||||
The collection path is determined from the first image. If the table consists of images from different
|
||||
collections, then only the first collection is used.
|
||||
|
||||
]]
|
||||
|
||||
dtutils_processor.libdoc.functions[#dtutils_processor.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Limitations"},
|
||||
Name = [[extract_collection_path - extract the collection path from an image table]],
|
||||
Synopsis = [[local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dp.extract_collection_path(image_table)
|
||||
image_table - table - a table of images such as supplied by the exporter or by libPlugin.build_image_table]],
|
||||
Description = [[extract_collection_path looks at the first image in the image_table and returns the path]],
|
||||
Return_Value = [[result - string - the collection path on success, or nil if there was an error]],
|
||||
Limitations = [[The collection path is determined from the first image. If the table consists of images from different
|
||||
collections, then only the first collection is used.]],
|
||||
}
|
||||
|
||||
function dtutils_processor.extract_collection_path(image_table)
|
||||
collection_path = nil
|
||||
for i,_ in pairs(image_table) do
|
||||
collection_path = i.path
|
||||
break
|
||||
end
|
||||
return collection_path
|
||||
end
|
||||
|
||||
--[[
|
||||
NAME
|
||||
make_output_filename- make an output filename from an image list
|
||||
|
||||
SYNOPSIS
|
||||
local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dtutils.make_output_filename(img_list)
|
||||
img_list - string - a space separated list of filenames
|
||||
|
||||
DESCRIPTION
|
||||
make_output_filename takes a string of filenames, breaks them apart, then
|
||||
combines them in a way that makes some sense. This is useful in routines
|
||||
that do panoramas, hdr, or focus stacks. The returned filename is a representation
|
||||
of the files used to construct the image. If there are 3 or fewer images, then the file
|
||||
basenames are concatenated with a separator. If there is more than 3 images, the first and
|
||||
last file basenames are concatenated with a separator.
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the constructed filename on success, nil on error
|
||||
|
||||
]]
|
||||
|
||||
dtutils_processor.libdoc.functions[#dtutils_processor.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[make_output_filename- make an output filename from an image list]],
|
||||
Synopsis = [[local dp = require "lib/dtutils.processor"
|
||||
|
||||
local result = dtutils.make_output_filename(img_list)
|
||||
img_list - string - a space separated list of filenames]],
|
||||
Description = [[make_output_filename takes a string of filenames, breaks them apart, then
|
||||
combines them in a way that makes some sense. This is useful in routines
|
||||
that do panoramas, hdr, or focus stacks. The returned filename is a representation
|
||||
of the files used to construct the image. If there are 3 or fewer images, then the file
|
||||
basenames are concatenated with a separator. If there is more than 3 images, the first and
|
||||
last file basenames are concatenated with a separator.]],
|
||||
Return_Value = [[result - string - the constructed filename on success, nil on error]],
|
||||
}
|
||||
|
||||
function dtutils_processor.make_output_filename(img_list)
|
||||
local images = {}
|
||||
local cnt = 1
|
||||
local max_distinct_names = 3
|
||||
local name_separator = "-"
|
||||
local outputFileName = nil
|
||||
log.msg(log.debug, "img_list is ", img_list)
|
||||
|
||||
local result = dtutils.split(img_list, " ")
|
||||
table.sort(result)
|
||||
for _,img in pairs(result) do
|
||||
images[cnt] = df.get_basename(img)
|
||||
cnt = cnt + 1
|
||||
end
|
||||
|
||||
cnt = cnt - 1
|
||||
|
||||
if cnt > 1 then
|
||||
if cnt > max_distinct_names then
|
||||
-- take the first and last
|
||||
outputFileName = images[1] .. name_separator .. images[cnt]
|
||||
else
|
||||
-- join them
|
||||
outputFileName = dtutils.join(images, name_separator)
|
||||
end
|
||||
else
|
||||
-- return the single name
|
||||
outputFileName = images[cnt]
|
||||
end
|
||||
|
||||
return outputFileName
|
||||
end
|
||||
|
||||
return dtutils_processor
|
||||
378
lib/libLog.lua
Normal file
378
lib/libLog.lua
Normal file
@@ -0,0 +1,378 @@
|
||||
--[[
|
||||
|
||||
libLog.lua - darktable lua logging library
|
||||
|
||||
Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
local libLog = {}
|
||||
libLog.libdoc = {
|
||||
Sections = {"Name", "Synopsis", "Description", "License", "Copyright"},
|
||||
Name = "libLog - darktable lua logging library",
|
||||
Synopsis = [[local log = require "lib/libLog"]],
|
||||
Description = [[libLog provides a multi-level logging solution for use with
|
||||
the darktable lua scripts.]],
|
||||
License = [[This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
|
||||
Copyright = "Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.",
|
||||
functions = {}
|
||||
}
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
-- set the default log levels
|
||||
|
||||
libLog.debug = {"DEBUG:", false}
|
||||
libLog.info = {"INFO:", false}
|
||||
libLog.warn = {"WARN:", false}
|
||||
libLog.error = {"ERROR:", true}
|
||||
libLog.success = {"SUCCESS:", true}
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = "caller - get the name of the calling routine",
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
result = log.caller(level)
|
||||
level - number - the number of stack levels to go down to retrieve the caller routine information]],
|
||||
Description = "caller gets the name of the calling routine and returns it",
|
||||
Return_Value = [[result - string - the name and line number of the calling function or 'callback: ' if the attempt to get the
|
||||
caller returns nil]],
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
caller - get the name of the calling routine
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
local result = log.caller(level)
|
||||
level - number - the number of stack levels to go down to retrieve the caller routine information
|
||||
|
||||
DESCRIPTION
|
||||
caller gets the name of the calling routine and returns it
|
||||
|
||||
RETURN VALUE
|
||||
result - string - the name of the calling function and line number or 'callback: ' if the attempt to get the
|
||||
caller returns nil
|
||||
|
||||
|
||||
]]
|
||||
|
||||
function libLog.caller(level)
|
||||
local name = debug.getinfo(level).name
|
||||
local lineno = nil
|
||||
local source = nil
|
||||
if name then
|
||||
lineno = debug.getinfo(level).currentline
|
||||
-- returns the path to the file prefixed with @
|
||||
source = debug.getinfo(level).source
|
||||
-- we just need the filename, so grab it from the string
|
||||
-- Thanks, Tobias Jakobs :-)
|
||||
source = string.match(source, "@.-([^\\/]-%.?[^%.\\/]*)$")
|
||||
return name .. ": " .. source .. ": " .. lineno .. ":"
|
||||
else
|
||||
return "callback:"
|
||||
end
|
||||
end
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Limitations"},
|
||||
Name = "msg - print a log message",
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
log.msg(level, ...)
|
||||
level - table - the type of message, one of:
|
||||
libLog.debug - debugging messages
|
||||
libLog.info - informational messages
|
||||
libLog.warn - warning messages
|
||||
libLog.error - error messages
|
||||
libLog.success - success messages
|
||||
... - string(s) - the message to print, which could be a comma separated set of strings]],
|
||||
Description = [[msg checks the level to see if it is enabled, then prints the level type and message if it is.
|
||||
debug messages print straight to the console, info and warn messages to dt.print_error() and error
|
||||
and success to dt.print()]],
|
||||
Limitations = [[If you use libLog.msg in a callback, the name of the calling routine can't be determined. A solution
|
||||
is to include some means of reference such as the name of the callback as an argument, i.e.
|
||||
|
||||
libLog.msg(libLog.debug, "libPlugin.format_combobox:", "value is " .. self.value)
|
||||
|
||||
which would result in
|
||||
|
||||
DEBUG: callback: libPlugin.format_combobox: value is JPEG]],
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
msg - print a log message
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
log.msg(level, ...)
|
||||
level - table - the type of message, one of:
|
||||
libLog.debug - debugging messages
|
||||
libLog.info - informational messages
|
||||
libLog.warn - warning messages
|
||||
libLog.error - error messages
|
||||
libLog.success - success messages
|
||||
... - string(s) - the message to print, which could be a comma separated set of strings
|
||||
|
||||
DESCRIPTION
|
||||
msg checks the level to see if it is enabled, then prints the level type and message if it is.
|
||||
debug messages print straight to the console, info and warn messages to dt.print_error() and error
|
||||
and success to dt.print()
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
LIMITATIONS
|
||||
If you use libLog.msg in a callback, the name of the calling routine can't be determined. A solution
|
||||
is to include some means of reference such as the name of the callback as an argument, i.e.
|
||||
|
||||
libLog.msg(libLog.debug, "libPlugin.format_combobox:", "value is " .. self.value)
|
||||
|
||||
which would result in
|
||||
|
||||
DEBUG: callback: libPlugin.format_combobox: value is JPEG
|
||||
|
||||
]]
|
||||
|
||||
function libLog.msg(level, ...)
|
||||
local message = {...}
|
||||
if level[2] == true then
|
||||
libLog.print(level[1], libLog.caller(3), unpack(message))
|
||||
end
|
||||
end
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value", "Reference"},
|
||||
Name = "print - print the supplied arguments",
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
log.print(...)
|
||||
... - arguments to be printed that are converted with tostring()]],
|
||||
Description = [[print loops through the arguments converting each to a string then writing
|
||||
them to stdout. Spaces are put between each argument on output.]],
|
||||
Return_Value = "none",
|
||||
Reference = "http://stackoverflow.com/questions/7148678/lua-print-on-the-same-line",
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
libLog.print - print the supplied arguments
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
log.print(...)
|
||||
... - arguments to be printed that are converted with tostring()
|
||||
|
||||
DESCRIPTION
|
||||
print loops through the arguments converting each to a string then writing
|
||||
them to stdout. Spaces are put between each argument on output.
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
REFERENCE
|
||||
http://stackoverflow.com/questions/7148678/lua-print-on-the-same-line
|
||||
|
||||
]]
|
||||
|
||||
function libLog.print(...)
|
||||
local write = io.write
|
||||
local n = select("#",...)
|
||||
for i = 1,n do
|
||||
local v = tostring(select(i,...))
|
||||
write(v)
|
||||
if i~=n then
|
||||
write(' ')
|
||||
end
|
||||
end
|
||||
write('\n')
|
||||
end
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[set_level - set the logging level]],
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
log.set_level(level)
|
||||
level - string - a string specifying the level, one of: "debug", "info", "warn", "error", "success"]],
|
||||
Description = [[set_level sets the logging level to the level specified. Every level above the specified level
|
||||
is also enabled, therefore specifying "debug" would turn on all levels and specifying "success"
|
||||
would turn all levels off except libLog.success.]],
|
||||
Return_Value = "none",
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
set_level - set the logging level
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
log.set_level(level)
|
||||
level - string - a string specifying the level, one of: "debug", "info", "warn", "error", "success"
|
||||
|
||||
DESCRIPTION
|
||||
set_level sets the logging level to the level specified. Every level above the specified level
|
||||
is also enabled, therefore specifying "debug" would turn on all levels and specifying "success"
|
||||
would turn all levels off except libLog.success.
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
]]
|
||||
|
||||
function libLog.set_level(level)
|
||||
level = level:lower()
|
||||
if string.match(level, "debug") then
|
||||
-- turn everything on
|
||||
libLog.debug[2] = true
|
||||
libLog.info[2] = true
|
||||
libLog.warn[2] = true
|
||||
libLog.error[2] = true
|
||||
libLog.success[2] = true
|
||||
elseif string.match(level, "info") then
|
||||
-- turn off debug and everything else on
|
||||
libLog.debug[2] = false
|
||||
libLog.info[2] = true
|
||||
libLog.warn[2] = true
|
||||
libLog.error[2] = true
|
||||
libLog.success[2] = true
|
||||
elseif string.match(level, "warn") then
|
||||
-- turn off debug and info and everything else on
|
||||
libLog.debug[2] = false
|
||||
libLog.info[2] = false
|
||||
libLog.warn[2] = true
|
||||
libLog.error[2] = true
|
||||
libLog.success[2] = true
|
||||
elseif string.match(level, "error") or string.match("reset") then
|
||||
-- everything off except error and success
|
||||
libLog.debug[2] = false
|
||||
libLog.info[2] = false
|
||||
libLog.warn[2] = false
|
||||
libLog.error[2] = true
|
||||
libLog.success[2] = true
|
||||
elseif string.match(level, "success") then
|
||||
-- everything off except success
|
||||
libLog.debug[2] = false
|
||||
libLog.info[2] = false
|
||||
libLog.warn[2] = false
|
||||
libLog.error[2] = false
|
||||
libLog.success[2] = true
|
||||
else
|
||||
-- leave everything unchanged and return
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description", "Return_Value"},
|
||||
Name = [[get_level - get the current logging level]],
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
local result = libLog.get_level()]],
|
||||
Description = "get_level returns a string representing the current log level.",
|
||||
Return_Value = [[result - string - one of "debug", "info", "warn", "error", or "success"]],
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
get_level - get the current logging level
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
local result = log.get_level()
|
||||
|
||||
DESCRIPTION
|
||||
get_level returns a string representing the current log level.
|
||||
|
||||
RETURN VALUE
|
||||
result - string - one of "debug", "info", "warn", "error", or "success"
|
||||
|
||||
]]
|
||||
|
||||
function libLog.get_level()
|
||||
local result = nil
|
||||
if libLog.debug[2] == true then
|
||||
result = "debug"
|
||||
elseif libLog.info[2] == true then
|
||||
result = "info"
|
||||
elseif libLog.warn[2] == true then
|
||||
result = "warn"
|
||||
elseif libLog.error[2] == true then
|
||||
result = "error"
|
||||
elseif libLog.success[2] == true then
|
||||
result = "success"
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
libLog.libdoc.functions[#libLog.libdoc.functions + 1] = {
|
||||
Sections = {"Name", "Synopsis", "Description"},
|
||||
Name = [[always - always write out a log message]],
|
||||
Synopsis = [[local log = require "lib/libLog"
|
||||
|
||||
log.always(level, ...)
|
||||
level - number - the number of stack levels to go back to identify the caller
|
||||
... - string(s) - the message to print]],
|
||||
Description = [[always is meant specifically for the dtutils.debug library, but may be used for other
|
||||
purposes. always is independent of the log level setting so that it will always work.
|
||||
The number of stack levels to look back for the caller may be specified. It is normally
|
||||
3 when called from a routine, but is 4 when called from the debugging routines since the
|
||||
debugging routines add another stack level.]],
|
||||
}
|
||||
|
||||
--[[
|
||||
NAME
|
||||
always - always write out a log message
|
||||
|
||||
SYNOPSIS
|
||||
local log = require "lib/libLog"
|
||||
|
||||
log.always(level, ...)
|
||||
level - number - the number of stack levels to go back to identify the caller
|
||||
... - string(s) - the message to print
|
||||
|
||||
DESCRIPTION
|
||||
always is meant specifically for the dtutils.debug library, but may be used for other
|
||||
purposes. always is independent of the log level setting so that it will always work.
|
||||
The number of stack levels to look back for the caller may be specified. It is normally
|
||||
3 when called from a routine, but is 4 when called from the debugging routines since the
|
||||
debugging routines add another stack level.
|
||||
]]
|
||||
|
||||
function libLog.always(level, ...)
|
||||
local message = {...}
|
||||
libLog.print(libLog.caller(level), unpack(message))
|
||||
end
|
||||
|
||||
return libLog
|
||||
@@ -1,93 +0,0 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2014 Jérémy Rosen
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
DEBUG HELPERS
|
||||
A collection of helper functions to help debugging lua scripts.
|
||||
|
||||
require it as
|
||||
|
||||
dhelpers = require "official/debug-helpers"
|
||||
|
||||
Each function is documented in its own header
|
||||
|
||||
|
||||
]]
|
||||
|
||||
|
||||
local dt = require "darktable"
|
||||
local io = require "io"
|
||||
local table = require "table"
|
||||
require "darktable.debug"
|
||||
local M = {} -- The actual content of the module
|
||||
|
||||
--[[
|
||||
A function which prints its name and its parameters
|
||||
* name : the name of the tracepoint
|
||||
* ... : anything, will be dumped using dt.debug
|
||||
]]
|
||||
function M.tracepoint(name,...)
|
||||
print("***** "..name.." ****")
|
||||
params = {...}
|
||||
print(dt.debug.dump(params,"parameters"))
|
||||
return ...;
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
A function that returns a tracepoint function with the given name
|
||||
This is mainly used to debug callbacks,
|
||||
|
||||
register_event(event, dhelpers.new_tracepoint("hit callback"))
|
||||
|
||||
will print the following each time the callback is called
|
||||
|
||||
**** hit callback ****
|
||||
<all the callback's parameters dumped>
|
||||
|
||||
]]
|
||||
function M.new_tracepoint(name)
|
||||
return function(...) return M.tracepoint(name,...) end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Wrapper around debug.dump, will directly print to stdout,
|
||||
same calling covention
|
||||
]]
|
||||
|
||||
function M.dprint(...)
|
||||
print(dt.debug.dump(...))
|
||||
end
|
||||
|
||||
--[[
|
||||
sets dt.debug.known to shorten all images to a single line
|
||||
|
||||
if you don't need to debug the content of images, this will avoid them flooding your logs
|
||||
]]
|
||||
function M.terse_dump()
|
||||
for _,v in ipairs(dt.database) do
|
||||
dt.debug.known[v] = tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
63
tools/get_lib_manpages.lua
Normal file
63
tools/get_lib_manpages.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
--[[
|
||||
get_lib_manpages.lua - retrieve the included library documentation and output it as man pages
|
||||
|
||||
Copyright (c) 2016, Bill Ferguson
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local libname = nil
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
local function output_man(d)
|
||||
local parts = du.split(d[d.Sections[1]], " - ")
|
||||
if not libname then
|
||||
libname = parts[1]
|
||||
end
|
||||
local fname = "/tmp/" .. parts[1] .. ".3"
|
||||
local mf = io.open(fname, "w")
|
||||
if mf then
|
||||
mf:write(".TH " .. string.upper(parts[1]) .. " 3 \"\" \"\" \"Darktable " .. libname .. " functions\"\n")
|
||||
for _,section in pairs(d.Sections) do
|
||||
if d[section] then
|
||||
mf:write(".SH " .. string.upper(string.gsub(section, "_", " ")) .. "\n")
|
||||
mf:write(d[section] .. "\n")
|
||||
end
|
||||
end
|
||||
mf:close()
|
||||
os.execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf")
|
||||
else
|
||||
log.msg(log.error, "Can't open file " .. fname .. "for writing")
|
||||
end
|
||||
end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
for line in output:lines() do
|
||||
line = string.gsub(line, "/", ".")
|
||||
local lib_name = line:sub(3,-5)
|
||||
if lib_name:len() > 2 then
|
||||
lib_name = "lib/" .. lib_name
|
||||
local lib = require(lib_name)
|
||||
|
||||
-- print the documentation for the library
|
||||
if lib.libdoc then
|
||||
local doc = lib.libdoc
|
||||
if doc then
|
||||
output_man(doc)
|
||||
for _,fdoc in pairs(doc.functions) do
|
||||
|
||||
-- print the documentation for each of the functions
|
||||
output_man(fdoc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
libname = nil
|
||||
end
|
||||
|
||||
46
tools/get_libdoc.lua
Normal file
46
tools/get_libdoc.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
--[[
|
||||
get_libdoc.lua - retrieve the included library documentation and output it
|
||||
|
||||
Copyright (c) 2016, Bill Ferguson
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
dt.configuration.check_version(...,{3,0,0})
|
||||
|
||||
local function output_doc(d)
|
||||
for _,section in pairs(d.Sections) do
|
||||
if d[section] then
|
||||
print(string.upper(string.gsub(section, "_", " ")))
|
||||
print("\t" .. d[section] .. "\n")
|
||||
end
|
||||
end
|
||||
print("\f")
|
||||
end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
for line in output:lines() do
|
||||
line = string.gsub(line, "/", ".")
|
||||
local lib_name = line:sub(3,-5)
|
||||
if lib_name:len() > 2 then
|
||||
lib_name = "lib/" .. lib_name
|
||||
local lib = require(lib_name)
|
||||
|
||||
-- print the documentation for the library
|
||||
if lib.libdoc then
|
||||
local doc = lib.libdoc
|
||||
output_doc(doc)
|
||||
for _,fdoc in pairs(doc.functions) do
|
||||
|
||||
-- print the documentation for each of the functions
|
||||
output_doc(fdoc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user