[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: please critique my first script
- From: Tommy Pettersson <ptp@...>
- Date: Sat, 21 Feb 2009 16:30:22 +0100
On Wed, Feb 18, 2009 at 04:57:27PM -0800, Florin Andrei wrote:
> Newbie here, I needed a pretext to learn Lua, so I made a script which
> takes a bunch of image files and sorts them neatly into folders based on
> the EXIF timestamp of each file.
[...]
> Please see the script attached to this message and comment on any mistakes,
> idiosyncrasies, faux pas, etc.
It's always a joy to code in Lua. The only thing better than to
write code when learning a new language is to read code. So I
rewrote your script, not to make it better but to make it
different, to show other ways in which Lua can work, and
hopefully give some new ideas.
Tables are central in Lua, and a powerful way to handle data, so
you better learn everything there is to know about them. :-)
I've simplified (in my opinion) your script a lot by just using
tables in a different way.
Regards,
Tommy
--
Tommy Pettersson <ptp@lysator.liu.se>
#!/usr/bin/lua
local usage_fmt =
[[
imgsort - script to sort image files based on their EXIF timestamp attributes
by Florin Andrei, 2009/02/18
Usage: %s <directory_containing_pictures>
]]
require 'lfs'
-- cache for speed and convenience
local match, gsub = string.match, string.gsub
local werr = function (...) io.stderr:write(...) end
-- Always require one argument
if table.maxn(arg) ~= 1 then
werr( string.format( usage_fmt, arg[0] ))
os.exit( 1 )
end
local dir = arg[1]
-- Locate exiv2 (the EXIF utility)
local extool do
local tmp = io.popen( 'which exiv2', 'r' )
extool = tmp:read()
tmp:close()
end
if not extool then
werr( 'Cannot find the exiv2 utility. Bye bye.\n' )
os.exit( 1 )
end
-- exiv2 outputs lines like:
-- dir/IMG_0373.JPG Image timestamp : 2008:11:07 16:43:50
--
-- Parse line and insert file path in array with date as key
local dates = {} --:: date => [path]
local excmd = io.popen( extool..' '..dir..'/*', 'r' )
for line in excmd:lines() do
local name, date = match( line, '^(.+) Image timestamp : ([:%d]+)' )
if date then
date = gsub( date, ':', '-' )
if not dates[date] then dates[date] = {} end
local names = dates[date]
names[#names+1] = name
end
end
excmd:close()
-- Move images to date directories
local split_path_and_filename =
function (name)
return match( name, '^(.*)/(.*)' ) --=> nil if can't split
end
for date, names in pairs( dates ) do
assert( lfs.mkdir( dir..'/'..date ))
for _,src in ipairs( names ) do
local _,filename = split_path_and_filename( src )
local dst = dir..'/'..date..'/'..(filename or src)
local ok, err = os.rename( src, dst )
if not ok then
werr( 'Could not move ',src,' to ',dst,': ',err,'\n' )
end
end
end