mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-14 15:08:22 +00:00
284 lines
7.2 KiB
Markdown
284 lines
7.2 KiB
Markdown
|
---
|
||
|
layout: default
|
||
|
title: "Example: Auto-Image-Magic"
|
||
|
tab: "manual/examples"
|
||
|
---
|
||
|
|
||
|
This [example](..) is a layer 1 script to make a special "magic" directory in which image files will be converted automatically therein.
|
||
|
|
||
|
The full script:
|
||
|
|
||
|
{% highlight lua %}
|
||
|
local formats = { jpg = true, gif = true, png = true }
|
||
|
|
||
|
convert = {
|
||
|
delay = 0,
|
||
|
|
||
|
maxProcesses = 99,
|
||
|
|
||
|
action = function(inlet)
|
||
|
local event = inlet.getEvent()
|
||
|
|
||
|
if event.isdir then
|
||
|
-- ignores events on dirs
|
||
|
inlet.discardEvent(event)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- extract extension and basefilename
|
||
|
local p = event.pathname
|
||
|
local ext = string.match(p, ".*%.([^.]+)$")
|
||
|
local base = string.match(p, "(.*)%.[^.]+$")
|
||
|
if not formats[ext] then
|
||
|
-- an unknown extenion
|
||
|
log("Normal", "not doing something on ."..ext)
|
||
|
inlet.discardEvent(event)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- autoconvert on create and modify
|
||
|
if event.etype == "Create" or event.etype == "Modify" then
|
||
|
-- builds one bash command
|
||
|
local cmd = ""
|
||
|
-- do for all other extensions
|
||
|
for k, _ in pairs(formats) do
|
||
|
if k ~= ext then
|
||
|
-- excludes files to be created, so no
|
||
|
-- followup actions will occur
|
||
|
inlet.addExclude(base..'.'..k)
|
||
|
if cmd ~= "" then
|
||
|
cmd = cmd .. " && "
|
||
|
end
|
||
|
cmd = cmd..
|
||
|
'/usr/bin/convert "'..
|
||
|
event.source..p..'" "'..
|
||
|
event.source..base..'.'..k..
|
||
|
'" || /bin/true'
|
||
|
end
|
||
|
end
|
||
|
log("Normal", "Converting "..p)
|
||
|
spawnShell(event, cmd)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- deletes all formats if you delete one
|
||
|
if event.etype == "Delete" then
|
||
|
-- builds one bash command
|
||
|
local cmd = ""
|
||
|
-- do for all other extensions
|
||
|
for k, _ in pairs(formats) do
|
||
|
if k ~= ext then
|
||
|
-- excludes files to be deleted, so no
|
||
|
-- followup actions will occur
|
||
|
inlet.addExclude(base..'.'..k)
|
||
|
if cmd ~= "" then
|
||
|
cmd = cmd .. " && "
|
||
|
end
|
||
|
cmd = cmd..
|
||
|
'rm "'..event.source..base..'.'..k..
|
||
|
'" || /bin/true'
|
||
|
end
|
||
|
end
|
||
|
log("Normal", "Deleting all "..p)
|
||
|
spawnShell(event, cmd)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- ignores other events.
|
||
|
inlet.discardEvent(event)
|
||
|
end,
|
||
|
|
||
|
-----
|
||
|
-- Removes excludes when convertions are finished
|
||
|
--
|
||
|
collect = function(event, exitcode)
|
||
|
local p = event.pathname
|
||
|
local ext = string.match(p, ".*%.([^.]+)$")
|
||
|
local base = string.match(p, "(.*)%.[^.]+$")
|
||
|
local inlet = event.inlet
|
||
|
|
||
|
if event.etype == "Create" or
|
||
|
event.etype == "Modify" or
|
||
|
event.etype == "Delete"
|
||
|
then
|
||
|
for k, _ in pairs(formats) do
|
||
|
inlet.rmExclude(base..'.'..k)
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
|
||
|
}
|
||
|
|
||
|
sync{convert, source="magicdir", recursive=false}
|
||
|
{% endhighlight %}
|
||
|
|
||
|
This creates a local table of all supported file formats. The file formats are used as keys.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
local formats = { jpg=true, gif=true, png=true, }
|
||
|
{% endhighlight %}
|
||
|
|
||
|
Configures actions to be instant and there is unlimits the amount the conversion to be done at once. Well not unlimited but set the limit pretty high.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
convert = {
|
||
|
delay = 0,
|
||
|
maxProcesses = 99,
|
||
|
{% endhighlight %}
|
||
|
|
||
|
This script uses the _layer 1_ inlet interface altough it greps only single events and not lists. It does this instead of _layer 2_ as it needs to do common operations for all kind of events.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
action = function(inlet)
|
||
|
local event = inlet.getEvent()
|
||
|
{% endhighlight %}
|
||
|
|
||
|
Ignores directories. As using _layer 1_ it has to explicitly discard events it does not spawn actions for.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
if event.isdir then
|
||
|
-- ignores events on dirs
|
||
|
inlet.discardEvent(event)
|
||
|
return
|
||
|
end
|
||
|
{% endhighlight %}
|
||
|
|
||
|
Uses Lua string patterns to extract the file extension from the rest - here called base.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- extract extension and basefilename
|
||
|
local p = event.pathname
|
||
|
local ext = string.match(p, ".*%.([^.]+)$")
|
||
|
local base = string.match(p, "(.*)%.[^.]+$")
|
||
|
{% endhighlight %}
|
||
|
|
||
|
Looks the extension up in the formats table. This can be done, since formats are keys in that table. If not an image format it bails out.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
if not formats[ext] then
|
||
|
-- an unknown extenion
|
||
|
log("Normal", "not doing something on ."..ext)
|
||
|
inlet.discardEvent(event)
|
||
|
return
|
||
|
end
|
||
|
{% endhighlight %}
|
||
|
|
||
|
|
||
|
Following actions will done on "Create" and "Modify" events.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- autoconvert on create and modify
|
||
|
if event.etype == "Create" or event.etype == "Modify" then
|
||
|
{% endhighlight %}
|
||
|
|
||
|
This script builds a bash command using a string.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- builds one bash command
|
||
|
local cmd = ""
|
||
|
{% endhighlight %}
|
||
|
|
||
|
It iterates for all image formats and excludes the one which is the source image.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- do for all other extensions
|
||
|
for k, _ in pairs(formats) do
|
||
|
if k ~= ext then
|
||
|
{% endhighlight %}
|
||
|
|
||
|
This is a little trick. It creates Exclusions for the converted images. As this images are not placed in a target directory but right next to the source image in the source directory they would otherwise trigger Create actions as well.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- excludes files to be created, so no
|
||
|
-- followup actions will occur
|
||
|
inlet.addExclude(base..'.'..k)
|
||
|
{% endhighlight %}
|
||
|
|
||
|
And for every image to be converted adds the calls to the arguments. It uses ```" || /bin/true "``` to let the shell continue if one conversion fails. In that it chains the conversion with '&&' they will be called sequentially.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
if cmd ~= "" then
|
||
|
cmd = cmd .. " && "
|
||
|
end
|
||
|
cmd = cmd..
|
||
|
'/usr/bin/convert "'..
|
||
|
event.source..p..'" "'..
|
||
|
event.source..base..'.'..k..
|
||
|
'" || /bin/true'
|
||
|
{% endhighlight %}
|
||
|
|
||
|
And eventually it spawns the shell doing the conversions and is finished.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
end
|
||
|
end
|
||
|
log("Normal", "Converting "..p)
|
||
|
spawnShell(event, cmd)
|
||
|
return
|
||
|
end
|
||
|
{% endhighlight %}
|
||
|
|
||
|
For deletions it does technically something similar, but it deletes all other file formats of the image.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- deletes all formats if you delete one
|
||
|
if event.etype == "Delete" then
|
||
|
-- builds one bash command
|
||
|
local cmd = ""
|
||
|
-- do for all other extensions
|
||
|
for k, _ in pairs(formats) do
|
||
|
if k ~= ext then
|
||
|
-- excludes files to be deleted, so no
|
||
|
-- followup actions will occur
|
||
|
inlet.addExclude(base..'.'..k)
|
||
|
if cmd ~= "" then
|
||
|
cmd = cmd .. " && "
|
||
|
end
|
||
|
cmd = cmd..
|
||
|
'rm "'..event.source..base..'.'..k..
|
||
|
'" || /bin/true'
|
||
|
end
|
||
|
end
|
||
|
log("Normal", "Deleting all "..p)
|
||
|
spawnShell(event, cmd)
|
||
|
return
|
||
|
end
|
||
|
{% endhighlight %}
|
||
|
|
||
|
and not to forget to nicely discard all other events.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-- ignores other events.
|
||
|
inlet.discardEvent(event)
|
||
|
end,
|
||
|
{% endhighlight %}
|
||
|
|
||
|
collect is called when the conversions finished. It will remove the temporary excludes again.
|
||
|
|
||
|
{% highlight lua %}
|
||
|
-----
|
||
|
-- Removes excludes when convertions are finished
|
||
|
--
|
||
|
collect = function(event, exitcode)
|
||
|
local p = event.pathname
|
||
|
local ext = string.match(p, ".*%.([^.]+)$")
|
||
|
local base = string.match(p, "(.*)%.[^.]+$")
|
||
|
local inlet = event.inlet
|
||
|
|
||
|
if event.etype == "Create" or
|
||
|
event.etype == "Modify" or
|
||
|
event.etype == "Delete"
|
||
|
then
|
||
|
for k, _ in pairs(formats) do
|
||
|
inlet.rmExclude(base..'.'..k)
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
{% endhighlight %}
|
||
|
|
||
|
And finally use the configuration to watch "magicdir".
|
||
|
|
||
|
{% highlight lua %}
|
||
|
sync{convert, source="magicdir", recursive=false}
|
||
|
{% endhighlight %}
|