-
Notifications
You must be signed in to change notification settings - Fork 3
/
movefiles.lua
120 lines (106 loc) · 3.75 KB
/
movefiles.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
-- Moves one or more files to a target directory.
-- Mind that this is the first Lua script I have ever written, so it could be dodgy.
-- The normal way of calling this script would be with a URL parameter 'target' for
-- the target directory, and one or more 'source' parameters pointing to files or
-- folders to be moved into the target.
-- However, because the Lua interface of the FlashAir only accepts URLs up to about
-- 155 bytes and has no support for POST, the parameters are next to useless for
-- longer paths. Hence I faked a POST request by allowing a parameter 'argfile'
-- that overrides the others, and points to a file containing a longer query string.
-- This is an ugly hack I'm not very proud of, so don't take it as an example of
-- good practice, it is merely necessary evil.
-- Part of FlashAir Fancy Web Interface by Dr. Lex
-- Released under BSD 2-Clause License. See other files for license details.
function urldecode(s)
local s = s:gsub('+', ' ')
:gsub('%%(%x%x)', function(h)
return string.char(tonumber(h, 16))
end)
return s
end
function parsequery(s)
local ans = {}
for k,v in s:gmatch('([^&=]-)=([^&=]+)' ) do
if ans[ k ] == nil then
ans[ k ] = {urldecode(v)}
else
table.insert(ans[ k ], urldecode(v))
end
end
return ans
end
function filename(s)
return string.gsub(s, "^.*/", "")
end
function printHttp(s)
print("HTTP/1.1 200 OK")
print("Content-Type: text/plain")
print("")
print(s)
end
argm = arg[1]
if argm == nil then
argm = ""
end
-- For some reason there is a newline at the end of argm: zap it.
queryFields = parsequery(string.gsub(argm, "\n$", ""))
if queryFields.argfile ~= nil then
local f = io.open(queryFields.argfile[1], "r")
if f then
argm = f:read("*all")
f:close()
queryFields = parsequery(string.gsub(argm, "\n$", ""))
else
printHttp("ERROR: cannot read argfile")
return
end
end
if queryFields.target == nil then
printHttp("ERROR: Missing parameter 'target'")
return
end
if queryFields.source == nil then
printHttp("ERROR: Missing parameter 'source'")
return
end
target = queryFields.target[1]
sources = queryFields.source
-- Do not omit the third argument, otherwise this Lua implementation will return garbage
if string.sub(target, -1, -1) ~= "/" then
target = target .. "/"
end
targetDir = string.gsub(target, "/$", "")
if target ~= "/" and lfs.attributes(targetDir, "mode") ~= "directory" then
printHttp("ERROR: Target directory '" .. targetDir .. "' does not exist")
return
end
for i=1, #sources, 1 do
-- Invoking fa.rename with a string concatenation makes the script go boom, therefore copy to separate variables. Don't ask me why.
local sourcePath = sources[i]
local targetPath = target .. filename(sources[i])
if lfs.attributes(sourcePath) == nil then
printHttp("ERROR: source file '" .. sourcePath .. "' does not exist, stopping move at this point")
return
end
-- Avoid pointless operations, this would append '(1)' to the filename.
if sourcePath ~= targetPath then
-- os.rename does not work and the alternative fa.rename has no return value, hence success of the operation must be tested separately
fa.rename(sourcePath, targetPath)
local failure = ""
if lfs.attributes(targetPath) == nil then
-- Checking attributes will sometimes fail when executed too soon after rename, therefore retry.
sleep(100) -- sleep, the secret sauce of fixing problems that shouldn't even occur.
if lfs.attributes(targetPath) == nil then
failure = failure .. "[target not found]"
end
end
if lfs.attributes(sourcePath) ~= nil then
failure = failure .. "[source still exists]"
end
if failure ~= "" then
printHttp("ERROR: failed to move '" .. sourcePath .. "' to '" .. targetPath .. "' " .. failure .. ". Stopping move at this point")
return
end
end
end
printHttp("SUCCESS")