1if not modules then modules = { } end modules ['trac-fil'] = {
2 version = 1.001,
3 comment = "for the moment for myself",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local rawset, tonumber, type, pcall, next = rawset, tonumber, type, pcall, next
10local format, concat = string.format, table.concat
11local openfile = io.open
12local date = os.date
13local sortedpairs = table.sortedpairs
14
15local P, C, Cc, Cg, Cf, Ct, Cs, Carg = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Ct, lpeg.Cs, lpeg.Carg
16local lpegmatch = lpeg.match
17
18local patterns = lpeg.patterns
19local cardinal = patterns.cardinal
20local whitespace = patterns.whitespace^0
21
22local timestamp = Cf(Ct("") * (
23 Cg (Cc("year") * (cardinal/tonumber)) * P("-")
24 * Cg (Cc("month") * (cardinal/tonumber)) * P("-")
25 * Cg (Cc("day") * (cardinal/tonumber)) * P(" ")
26 * Cg (Cc("hour") * (cardinal/tonumber)) * P(":")
27 * Cg (Cc("minute") * (cardinal/tonumber)) * P(":")
28 * Cg (Cc("second") * (cardinal/tonumber)) * P("+")
29 * Cg (Cc("thour") * (cardinal/tonumber)) * P(":")
30 * Cg (Cc("tminute") * (cardinal/tonumber))
31)^0, rawset)
32
33local keysvalues = Cf(Ct("") * (
34 Cg(C(patterns.letter^0) * whitespace * "=" * whitespace * Cs(patterns.unquoted) * whitespace)
35)^0, rawset)
36
37local statusline = Cf(Ct("") * (
38 whitespace * P("[") * Cg(Cc("timestamp") * timestamp ) * P("]")
39 * whitespace * Cg(Cc("status" ) * keysvalues)
40),rawset)
41
42patterns.keysvalues = keysvalues
43patterns.statusline = statusline
44patterns.timestamp = timestamp
45
46loggers = loggers or { }
47
48local timeformat = format("[%%s%s]",os.timezone())
49local dateformat = "!%Y-%m-%d %H:%M:%S"
50
51function loggers.makeline(t)
52 local result = { }
53 result[#result+1] = format(timeformat,date(dateformat))
54 for k, v in sortedpairs(t) do
55 local tv = type(v)
56 if tv == "string" then
57 if v ~= "password" then
58 result[#result+1] = format(" %s=%q",k,v)
59 end
60 elseif tv == "number" or tv == "boolean" then
61 result[#result+1] = format(" %s=%q",k,tostring(v))
62 end
63 end
64 return concat(result," ")
65end
66
67local function append(filename,...)
68 local f = openfile(filename,"a+")
69 if not f then
70 dir.mkdirs(file.dirname(filename))
71 f = openfile(filename,"a+")
72 end
73 if f then
74 f:write(...)
75 f:close()
76 return true
77 else
78 return false
79 end
80end
81
82function loggers.store(filename,data)
83 if type(data) == "table"then
84 data = loggers.makeline(data)
85 end
86 pcall(append,filename,data,"\n")
87end
88
89function loggers.collect(filename,result)
90 if lfs.isfile(filename) then
91 local r = lpegmatch(Ct(statusline^0),io.loaddata(filename))
92 if result then
93 local nofresult = #result
94 for i=1,#r do
95 nofresult = nofresult + 1
96 result[nofresult] = r[i]
97 end
98 return result
99 else
100 return r
101 end
102 else
103 return result or { }
104 end
105end
106
107function loggers.fields(results)
108 local fields = { }
109 if results then
110 for i=1,#results do
111 local r = results[i]
112 for k, v in next, r do
113 local f = fields[k]
114 if not f then
115 fields[k] = 1
116 else
117 fields[k] = f + 1
118 end
119 end
120 end
121 end
122 return fields
123end
124
125local template = [[<!-- log entries: begin --!>
126<table>
127<tr>%s</tr>
128%s
129</table>
130<!-- log entries: end --!>
131]]
132
133function loggers.tohtml(entries,fields)
134 if not fields or #fields == 0 then
135 return ""
136 end
137 if type(entries) == "string" then
138 entries = loggers.collect(entries)
139 end
140 local scratch, lines = { }, { }
141 for i=1,#entries do
142 local entry = entries[i]
143 local status = entry.status
144 for i=1,#fields do
145 local field = fields[i]
146 local v = status[field.name]
147 if v ~= nil then
148 v = tostring(v)
149 local f = field.format
150 if f then
151 v = format(f,v)
152 end
153 scratch[i] = format("<td nowrap='nowrap' align='%s'>%s</td>",field.align or "left",v)
154 else
155 scratch[i] = "<td/>"
156 end
157 end
158 lines[i] = format("<tr>%s</tr>",concat(scratch))
159 end
160 for i=1,#fields do
161 local field = fields[i]
162 scratch[i] = format("<th nowrap='nowrap' align='left'>%s</th>", field.label or field.name)
163 end
164 local result = format(template,concat(scratch),concat(lines,"\n"))
165 return result, entries
166end
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 |