trac-fil.lua /size: 5313 b    last modification: 2021-10-28 13:50
1
if
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 9
local
rawset
,
tonumber
,
type
,
pcall
,
next
=
rawset
,
tonumber
,
type
,
pcall
,
next
10
local
format
,
concat
=
string
.
format
,
table
.
concat
11
local
openfile
=
io
.
open
12
local
date
=
os
.
date
13
local
sortedpairs
=
table
.
sortedpairs
14 15
local
P
,
C
,
Cc
,
Cg
,
Cf
,
Ct
,
Cs
,
Carg
=
lpeg
.
P
,
lpeg
.
C
,
lpeg
.
Cc
,
lpeg
.
Cg
,
lpeg
.
Cf
,
lpeg
.
Ct
,
lpeg
.
Cs
,
lpeg
.
Carg
16
local
lpegmatch
=
lpeg
.
match
17 18
local
patterns
=
lpeg
.
patterns
19
local
cardinal
=
patterns
.
cardinal
20
local
whitespace
=
patterns
.
whitespace
^
0
21 22
local
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 33
local
keysvalues
=
Cf
(
Ct
(
"
"
)
*
(
34
Cg
(
C
(
patterns
.
letter
^
0
)
*
whitespace
*
"
=
"
*
whitespace
*
Cs
(
patterns
.
unquoted
)
*
whitespace
)
35
)
^
0
,
rawset
)
36 37
local
statusline
=
Cf
(
Ct
(
"
"
)
*
(
38
whitespace
*
P
(
"
[
"
)
*
Cg
(
Cc
(
"
timestamp
"
)
*
timestamp
)
*
P
(
"
]
"
)
39
*
whitespace
*
Cg
(
Cc
(
"
status
"
)
*
keysvalues
)
40
)
,
rawset
)
41 42
patterns
.
keysvalues
=
keysvalues
43
patterns
.
statusline
=
statusline
44
patterns
.
timestamp
=
timestamp
45 46
loggers
=
loggers
or
{
}
47 48
local
timeformat
=
format
(
"
[%%s%s]
"
,
os
.
timezone
(
)
)
49
local
dateformat
=
"
!%Y-%m-%d %H:%M:%S
"
50 51
function
loggers
.
makeline
(
t
)
52
local
result
=
{
}
-- minimize time that file is open
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
,
"
"
)
65
end
66 67
local
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
80
end
81 82
function
loggers
.
store
(
filename
,
data
)
-- a log service is nicer
83
if
type
(
data
)
=
=
"
table
"
then
84
data
=
loggers
.
makeline
(
data
)
85
end
86
pcall
(
append
,
filename
,
data
,
"
\n
"
)
87
end
88 89
function
loggers
.
collect
(
filename
,
result
)
90
if
lfs
.
isfile
(
filename
)
then
91
local
r
=
lpegmatch
(
Ct
(
statusline
^
0
)
,
io
.
loaddata
(
filename
)
)
92
if
result
then
-- append
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
105
end
106 107
function
loggers
.
fields
(
results
)
-- returns hash of fields with counts so that we can decide on importance
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
123
end
124 125
local
template
=
[[
<!-- log entries: begin --!> 126<table> 127<tr>%s</tr> 128%s 129</table> 130<!-- log entries: end --!> 131
]]
132 133
function
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
166
end
167 168
-- loggers.store("test.log", { name = "whatever", more = math.random(1,100) })
169 170
-- local fields = {
171
-- { name = "name", align = "left" },
172
-- { name = "more", align = "right" },
173
-- }
174 175
-- local entries = loggers.collect("test.log")
176
-- local html = loggers.tohtml(entries,fields)
177 178
-- inspect(entries)
179
-- inspect(fields)
180
-- inspect(html)
181 182