Skip to content

Instantly share code, notes, and snippets.

@jney
Created October 20, 2009 22:06
Show Gist options
  • Save jney/214659 to your computer and use it in GitHub Desktop.
Save jney/214659 to your computer and use it in GitHub Desktop.
#!/usr/bin/env lua
-- This program aims to compress too big image when they are uploded
-- A directory and every subdirectories are watched via lua inotify binding :
-- http://github.com/hoelzro/linotify/
--
--
--
--
-- Requirements :
--
-- * lua
-- * linotify : http://github.com/hoelzro/linotify/
-- * lfs : http://www.keplerproject.org/luafilesystem/manual.html
-- * ruby
-- * smusher : gem install smusher
require "lfs"
-- variables
local inotify = require 'inotify'
local handle = inotify.init()
-- watched root dir
local root = "."
-- who will received the emails if it is too big
local emails = {"[email protected]"}
-- global vars
dirs = {}
-- max size is 200Ko
-- 1Ko = 1024 bytes
max_size_in_bytes = 1024 * 200
-- a function that return a tree of dirs
function dirtree(dir)
assert(dir and dir ~= "", "directory parameter is missing or empty")
if string.sub(dir, -1) == "/" then
dir=string.sub(dir, 1, -2)
end
local function yieldtree(dir)
for entry in lfs.dir(dir) do
if entry ~= "." and entry ~= ".." then
entry=dir.."/"..entry
local attr=lfs.attributes(entry)
if attr.mode == "directory" then
coroutine.yield(entry,attr)
yieldtree(entry)
end
end
end
end
return coroutine.wrap(function() yieldtree(dir) end)
end
function is_image(p)
return p and (
((string.len(p) > 4) and (string.lower(string.sub(p, -4)) == ".jpg")) or
((string.len(p) > 5) and (string.lower(string.sub(p, -5)) == ".jpeg")) or
((string.len(p) > 4) and (string.lower(string.sub(p, -4)) == ".png")) or
((string.len(p) > 4) and (string.lower(string.sub(p, -4)) == ".gif")))
end
function is_oversized(p)
return lfs.attributes(p).size > max_size_in_bytes
end
function watch_dir(p)
dirs[handle:addwatch(p, inotify.IN_CREATE)] = p
end
-- watching root
watch_dir(root)
-- watching every subdirectory
for filename in dirtree(".") do
watch_dir(filename)
end
-- infinite loop
while true do
local events = handle:read()
for _, ev in ipairs(events) do
local path = dirs[ev.wd].."/"..ev.name
-- if it's a dir we stating to watch it
if lfs.attributes(path).mode == "directory" then
-- we need first to have full path
dirs[handle:addwatch(path, inotify.IN_CREATE)] = path
elseif is_image(path) then
os.execute("smusher "..path.." -c")
end
if is_oversized(path) and (is_png(path) or is_jpeg(path)) then
os.execute("echo '"..path.." is too big' | mail -s 'too big image has been just uploaded' "..table.concat(emails," "))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment