Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
I3csstatus
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jiří Kalvoda
I3csstatus
Commits
11fcd08b
Commit
11fcd08b
authored
2 years ago
by
Jiří Kalvoda
Browse files
Options
Downloads
Patches
Plain Diff
Init Parser and add some module used it
parent
5e89ced8
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Parsers.cs
+186
-0
186 additions, 0 deletions
Parsers.cs
Program.cs
+110
-43
110 additions, 43 deletions
Program.cs
with
296 additions
and
43 deletions
Parsers.cs
0 → 100644
+
186
−
0
View file @
11fcd08b
#nullable enable
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Text.Json
;
using
System.Text.Json.Nodes
;
using
System.Linq
;
using
System.Threading
;
using
Color
=
System
.
Drawing
.
Color
;
using
Process
=
System
.
Diagnostics
.
Process
;
using
Config
;
namespace
i3csstatus
;
static
class
TimeShow
{
static
public
string
Show
(
long
t_s
)
{
if
(
t_s
<
180
)
return
$"
{
t_s
}
s"
;
if
(
t_s
<
180
*
60
)
return
$"
{
t_s
/
60
}
min"
;
return
$"
{
t_s
/
60
/
60
}
h"
;
}
static
public
string
WithSign
(
long
t_s
)
{
if
(
t_s
>=
0
)
return
"+"
+
Show
(
t_s
);
else
return
"-"
+
Show
(-
t_s
);
}
}
[
System
.
AttributeUsage
(
System
.
AttributeTargets
.
Class
,
AllowMultiple
=
true
)]
class
ParserName
:
System
.
Attribute
{
public
string
Name
{
get
;
init
;}
public
ParserName
(
string
_name
)
{
Name
=
_name
;
}
}
class
ParserGetter
:
GlobalModuleResource
{
Dictionary
<
string
,
Type
>
parserTypes
;
public
ParserGetter
()
{
parserTypes
=
new
Dictionary
<
string
,
Type
>(
from
assembly
in
AppDomain
.
CurrentDomain
.
GetAssemblies
()
from
type
in
assembly
.
GetTypes
()
where
type
.
IsDefined
(
typeof
(
ParserName
),
false
)
where
typeof
(
Parser
).
IsAssignableFrom
(
type
)
from
name
in
type
.
GetCustomAttributes
(
typeof
(
ParserName
),
false
)
select
new
KeyValuePair
<
string
,
Type
>(((
ParserName
)
name
).
Name
,
type
)
);
}
public
Parser
?
ByName
(
string
name
)
{
var
constructorSignature
=
new
Type
[]{};
if
(!
parserTypes
.
ContainsKey
(
name
))
return
null
;
var
constructor
=
parserTypes
[
name
].
GetConstructor
(
constructorSignature
);
if
(
constructor
==
null
)
throw
new
Exception
(
$"Missing constructor of
{
name
}
parser"
);
return
(
Parser
)
constructor
.
Invoke
(
new
object
[]{});
}
public
Parser
ByNameFromConfig
(
ConfigValue
val
)
{
if
(
val
==
null
)
return
new
ParserText
();
var
p
=
ByName
(
val
.
AsString
());
if
(
p
==
null
)
throw
new
ConfigMistake
(
val
,
$"Parser with name
{
val
.
AsString
()}
not exists."
);
return
p
;
}
}
interface
Parser
{
IEnumerable
<
Element
>
Parse
(
string
s
);
void
Init
(
StatusBar
_bar
,
Module
_module
,
ConfigSection
section
);
}
[
ParserName
(
"text"
)]
class
ParserText
:
Parser
{
Color
color
;
public
void
Init
(
StatusBar
_bar
,
Module
_module
,
ConfigSection
section
)
{
color
=
section
.
Optional
(
"color"
)?.
AsColor
()
??
System
.
Drawing
.
ColorTranslator
.
FromHtml
(
"white"
);
}
public
IEnumerable
<
Element
>
Parse
(
string
data
)
{
if
(
data
.
Length
>
0
&&
data
[^
1
]
==
'\n'
)
data
=
data
[..^
1
];
return
data
.
Split
(
"\n"
).
Select
(
x
=>
new
Element
(
x
,
color
:
color
)).
ToArray
();
}
}
[
ParserName
(
"osdd_last"
)]
class
ParserOsddLast
:
Parser
{
public
void
Init
(
StatusBar
_bar
,
Module
_module
,
ConfigSection
section
)
{
}
public
IEnumerable
<
Element
>
Parse
(
string
data
)
{
var
lines
=
data
.
Split
(
"\n"
);
if
(
lines
.
Length
>=
1
)
{
List
<
Element
>
output
=
new
();
long
timeEleapsed_s
=
DateTimeOffset
.
Now
.
ToUnixTimeSeconds
()-
long
.
Parse
(
lines
[
0
]);
bool
first
=
true
;
foreach
(
var
l
in
lines
[
1
..])
{
if
(
l
.
Length
>
7
)
output
.
Add
(
new
Element
((
first
?
$"[
{
TimeShow
.
Show
(
timeEleapsed_s
)}
] "
:
""
)
+
l
[
7
..],
color
:
System
.
Drawing
.
ColorTranslator
.
FromHtml
(
"#"
+
l
[..
6
])));
first
=
false
;
}
return
output
;
}
else
{
return
new
Element
[]{
new
Element
(
"OSDD parse ERROR"
,
color
:
Color
.
Red
)};
}
}
}
[
ParserName
(
"ICE_speed"
)]
class
ParserICESpeed
:
Parser
{
#
pragma
warning
disable
8602
public
void
Init
(
StatusBar
_bar
,
Module
_module
,
ConfigSection
section
)
{
}
public
IEnumerable
<
Element
>
Parse
(
string
data
)
{
try
{
JsonObject
json
=
JsonObject
.
Parse
(
data
).
AsObject
();
return
new
Element
[]{
new
Element
(
$"
{
json
[
"speed"
].
GetValue
<
double
>()}
km/h"
,
color
:
Color
.
White
)};
}
catch
(
Exception
e
)
{
Console
.
Error
.
WriteLine
(
e
);
return
new
Element
[]{
new
Element
(
"Speed PE"
,
color
:
Color
.
Red
)};
}
}
#
pragma
warning
restore
8602
}
[
ParserName
(
"ICE_next_stop"
)]
class
ParserICENextStop
:
Parser
{
#
pragma
warning
disable
8602
public
void
Init
(
StatusBar
_bar
,
Module
_module
,
ConfigSection
section
)
{
}
public
IEnumerable
<
Element
>
Parse
(
string
data
)
{
try
{
JsonObject
?
json
=
JsonObject
.
Parse
(
data
).
AsObject
();
JsonObject
?
nextStop
=
null
;
string
nextStopID
=
json
[
"trip"
].
AsObject
()[
"stopInfo"
].
AsObject
()[
"actualNext"
].
GetValue
<
string
>();
foreach
(
var
s
in
json
[
"trip"
].
AsObject
()[
"stops"
].
AsArray
())
{
string
id
=
s
.
AsObject
()[
"station"
].
AsObject
()[
"evaNr"
].
GetValue
<
string
>();
if
(
id
==
nextStopID
)
nextStop
=
s
.
AsObject
();
}
string
nextStopName
=
nextStop
[
"station"
].
AsObject
()[
"name"
].
GetValue
<
string
>();
long
nextStopArrival
=
nextStop
[
"timetable"
].
AsObject
()[
"actualArrivalTime"
].
GetValue
<
long
>()/
1000
;
long
nextStopArrivalScheudled
=
nextStop
[
"timetable"
].
AsObject
()[
"scheduledArrivalTime"
].
GetValue
<
long
>()/
1000
;
long
arrivalIn
=
nextStopArrival
-
DateTimeOffset
.
Now
.
ToUnixTimeSeconds
();
string
delayStr
=
nextStopArrivalScheudled
==
nextStopArrival
?
""
:
$" (
{
TimeShow
.
WithSign
(
nextStopArrival
-
nextStopArrivalScheudled
)}
)"
;
return
new
Element
[]{
new
Element
(
$"
{
nextStopName
}
in
{
TimeShow
.
Show
(
arrivalIn
)}
"
+
delayStr
,
color
:
Color
.
White
)};
}
catch
(
Exception
e
)
{
Console
.
Error
.
WriteLine
(
e
);
return
new
Element
[]{
new
Element
(
"ICE PE"
,
color
:
Color
.
Red
)};
}
}
#
pragma
warning
restore
8602
}
This diff is collapsed.
Click to expand it.
Program.cs
+
110
−
43
View file @
11fcd08b
...
@@ -16,6 +16,7 @@ using System.Runtime.InteropServices;
...
@@ -16,6 +16,7 @@ using System.Runtime.InteropServices;
using
Color
=
System
.
Drawing
.
Color
;
using
Color
=
System
.
Drawing
.
Color
;
using
Process
=
System
.
Diagnostics
.
Process
;
using
Process
=
System
.
Diagnostics
.
Process
;
using
System.Net.Http
;
using
Config
;
using
Config
;
...
@@ -109,14 +110,13 @@ namespace i3csstatus {
...
@@ -109,14 +110,13 @@ namespace i3csstatus {
class
ModuleFile
:
Module
class
ModuleFile
:
Module
{
{
string
path
;
string
path
;
protected
Color
color
;
InnerStatusBar
ifNotFound
;
InnerStatusBar
ifNotFound
;
InnerStatusBar
ifReadError
;
InnerStatusBar
ifReadError
;
Parser
parser
;
public
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
public
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
{
{
path
=
section
.
Mandatory
(
"path"
).
AsPath
();
path
=
section
.
Mandatory
(
"path"
).
AsPath
();
color
=
section
.
Optional
(
"color"
)?.
AsColor
()
??
System
.
Drawing
.
ColorTranslator
.
FromHtml
(
"white"
);
ifNotFound
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"not_found_handler"
)?.
AsConfig
()
??
ifNotFound
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"not_found"
)?.
AsConfig
()
??
section
.
Optional
(
"read_error"
)?.
AsConfig
()
??
section
.
Optional
(
"read_error"
)?.
AsConfig
()
??
new
ConfigParser
(
new
ConfigParser
(
@"
@"
...
@@ -124,18 +124,15 @@ namespace i3csstatus {
...
@@ -124,18 +124,15 @@ namespace i3csstatus {
color = red
color = red
text = NFound
text = NFound
"
));
"
));
ifReadError
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"
read_erro
r"
)?.
AsConfig
()
??
ifReadError
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"
error_handle
r"
)?.
AsConfig
()
??
new
ConfigParser
(
new
ConfigParser
(
@"
@"
[constant]
[constant]
color = red
color = red
text = ERR
text = ERR
"
));
"
));
}
parser
=
_bar
.
GetGlobal
<
ParserGetter
>().
ByNameFromConfig
(
section
.
Optional
(
"parser"
));
protected
virtual
IEnumerable
<
Element
>
Parse
(
string
text
)
parser
.
Init
(
_bar
,
this
,
section
);
{
if
(
text
.
Length
>
0
&&
text
[^
1
]
==
'\n'
)
text
=
text
[..^
1
];
return
text
.
Split
(
"\n"
).
Select
(
x
=>
new
Element
(
x
,
color
:
color
)).
ToArray
();
}
}
public
IEnumerable
<
Element
>
Get
()
public
IEnumerable
<
Element
>
Get
()
{
{
...
@@ -144,15 +141,16 @@ text = ERR
...
@@ -144,15 +141,16 @@ text = ERR
{
{
text
=
File
.
ReadAllText
(
path
);
text
=
File
.
ReadAllText
(
path
);
}
}
catch
(
Exception
e
x
)
when
(
e
x
is
FileNotFoundException
||
e
x
is
DirectoryNotFoundException
)
catch
(
Exception
e
)
when
(
e
is
FileNotFoundException
||
e
is
DirectoryNotFoundException
)
{
{
return
ifNotFound
.
Get
();
return
ifNotFound
.
Get
();
}
}
catch
(
Exception
)
catch
(
Exception
e
)
{
{
Console
.
Error
.
WriteLine
(
e
);
return
ifReadError
.
Get
();
return
ifReadError
.
Get
();
}
}
return
Parse
(
text
);
return
parser
.
Parse
(
text
);
}
}
}
}
[
ModuleName
(
"pipe"
)]
[
ModuleName
(
"pipe"
)]
...
@@ -161,18 +159,17 @@ text = ERR
...
@@ -161,18 +159,17 @@ text = ERR
StatusBar
bar
;
StatusBar
bar
;
string
path
;
string
path
;
string
text
;
string
text
;
protected
Color
color
;
InnerStatusBar
ifNoData
;
InnerStatusBar
ifNoData
;
InnerStatusBar
ifReadError
;
InnerStatusBar
ifReadError
;
Thread
inputThread
;
Thread
inputThread
;
int
msgSeparator
;
int
msgSeparator
;
int
scheudleIn_ms
;
int
scheudleIn_ms
;
bool
pipeError
=
false
;
bool
pipeError
=
false
;
Parser
parser
;
public
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
public
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
{
{
bar
=
_bar
;
bar
=
_bar
;
path
=
section
.
Mandatory
(
"path"
).
AsPath
();
path
=
section
.
Mandatory
(
"path"
).
AsPath
();
color
=
section
.
Optional
(
"color"
)?.
AsColor
()
??
System
.
Drawing
.
ColorTranslator
.
FromHtml
(
"white"
);
ifNoData
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"no_data"
)?.
AsConfig
()
??
ifNoData
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"no_data"
)?.
AsConfig
()
??
new
ConfigParser
(
new
ConfigParser
(
@"
@"
...
@@ -186,6 +183,9 @@ text = ERR
...
@@ -186,6 +183,9 @@ text = ERR
"
));
"
));
msgSeparator
=
section
.
Optional
(
"separator"
)?.
AsInt
()
??
0
;
msgSeparator
=
section
.
Optional
(
"separator"
)?.
AsInt
()
??
0
;
scheudleIn_ms
=
section
.
Optional
(
"delay"
)?.
AsMs
()
??
10
;
scheudleIn_ms
=
section
.
Optional
(
"delay"
)?.
AsMs
()
??
10
;
parser
=
_bar
.
GetGlobal
<
ParserGetter
>().
ByNameFromConfig
(
section
.
Optional
(
"parser"
));
parser
.
Init
(
_bar
,
this
,
section
);
inputThread
=
new
Thread
(
this
.
inputThreadFunc
);
inputThread
=
new
Thread
(
this
.
inputThreadFunc
);
inputThread
.
IsBackground
=
true
;
inputThread
.
IsBackground
=
true
;
inputThread
.
Start
();
inputThread
.
Start
();
...
@@ -228,11 +228,6 @@ text = ERR
...
@@ -228,11 +228,6 @@ text = ERR
}
}
}
}
}
}
protected
virtual
IEnumerable
<
Element
>
Parse
(
string
text
)
{
if
(
text
.
Length
>
0
&&
text
[^
1
]
==
'\n'
)
text
=
text
[..^
1
];
return
text
.
Split
(
"\n"
).
Select
(
x
=>
new
Element
(
x
,
color
:
color
)).
ToArray
();
}
public
IEnumerable
<
Element
>
Get
()
public
IEnumerable
<
Element
>
Get
()
{
{
string
_text
;
string
_text
;
...
@@ -244,42 +239,114 @@ text = ERR
...
@@ -244,42 +239,114 @@ text = ERR
return
ifReadError
.
Get
();
return
ifReadError
.
Get
();
if
(
_text
==
null
)
if
(
_text
==
null
)
return
ifNoData
.
Get
();
return
ifNoData
.
Get
();
return
Parse
(
_text
);
return
parser
.
Parse
(
_text
);
}
}
}
}
[
ModuleName
(
"
osdd_last
"
)]
[
ModuleName
(
"
http
"
)]
class
Module
OsddLast
:
Module
Pipe
class
Module
Http
:
Module
{
{
public
new
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
StatusBar
bar
;
string
url
;
string
text
;
HttpRequestException
error
;
long
dataTick
;
InnerStatusBar
ifNoData
;
InnerStatusBar
ifReadError
;
Thread
inputThread
;
int
period_ms
;
Parser
parser
;
int
maxOld_ms
;
int
showOld_ms
;
int
timeout_ms
;
public
void
Init
(
StatusBar
_bar
,
ConfigParser
config
,
ConfigSection
section
)
{
{
base
.
Init
(
_bar
,
config
,
section
);
bar
=
_bar
;
url
=
section
.
Mandatory
(
"url"
).
AsString
();
ifNoData
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"no_data_handler"
)?.
AsConfig
()
??
new
ConfigParser
(
@"
"
));
ifReadError
=
new
InnerStatusBar
(
_bar
,
section
.
Optional
(
"error_handler"
)?.
AsConfig
()
??
new
ConfigParser
(
@"
[constant]
color = red
text = ERR
"
));
period_ms
=
section
.
Optional
(
"period"
)?.
AsMs
()
??
10000
;
timeout_ms
=
section
.
Optional
(
"period"
)?.
AsMs
()
??
10000
;
showOld_ms
=
section
.
Optional
(
"show_old"
)?.
AsMs
()
??
30000
;
maxOld_ms
=
section
.
Optional
(
"max_old"
)?.
AsMs
()
??
300000
;
parser
=
_bar
.
GetGlobal
<
ParserGetter
>().
ByNameFromConfig
(
section
.
Optional
(
"parser"
));
parser
.
Init
(
_bar
,
this
,
section
);
inputThread
=
new
Thread
(
this
.
inputThreadFunc
);
inputThread
.
IsBackground
=
true
;
inputThread
.
Start
();
}
}
static
string
timeShow
(
long
t_s
)
async
void
inputThreadFunc
(
)
{
{
if
(
t_s
<
180
)
return
$"
{
t_s
}
s"
;
while
(
true
)
if
(
t_s
<
180
*
60
)
return
$"
{
t_s
/
60
}
min"
;
return
$"
{
t_s
/
60
/
60
}
h"
;
}
protected
override
IEnumerable
<
Element
>
Parse
(
string
text
)
{
{
try
try
{
{
var
lines
=
text
.
Split
(
"\n"
);
long
t
=
Environment
.
TickCount64
;
List
<
Element
>
output
=
new
();
using
var
client
=
new
HttpClient
();
long
timeEleapsed_s
=
DateTimeOffset
.
Now
.
ToUnixTimeSeconds
()-
long
.
Parse
(
lines
[
0
]);
client
.
Timeout
=
TimeSpan
.
FromMilliseconds
(
10000
);
bool
first
=
true
;
client
.
DefaultRequestHeaders
.
Add
(
"User-Agent"
,
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"
);
foreach
(
var
l
in
lines
[
1
..])
string
_text
=
await
client
.
GetStringAsync
(
url
);
lock
(
this
)
{
{
if
(
l
.
Length
>
7
)
dataTick
=
t
;
output
.
Add
(
new
Element
((
first
?
$"[
{
timeShow
(
timeEleapsed_s
)}
] "
:
""
)
+
l
[
7
..],
color
:
System
.
Drawing
.
ColorTranslator
.
FromHtml
(
"#"
+
l
[..
6
])));
text
=
_text
;
first
=
false
;
error
=
null
;
}
}
catch
(
HttpRequestException
e
)
{
if
(
e
.
StatusCode
!=
null
)
lock
(
this
)
{
error
=
e
;
}
}
catch
(
System
.
Threading
.
Tasks
.
TaskCanceledException
)
{
}
Thread
.
Sleep
(
period_ms
);
}
}
return
output
;
}
}
catch
(
Exception
)
public
IEnumerable
<
Element
>
Get
()
{
string
_text
;
long
_dataTick
;
HttpRequestException
_error
;
lock
(
this
)
{
_text
=
text
;
_dataTick
=
dataTick
;
_error
=
error
;
}
long
t
=
Environment
.
TickCount64
;
if
(
_error
!=
null
)
return
ifReadError
.
Get
();
if
(
_text
==
null
)
return
ifNoData
.
Get
();
if
(
maxOld_ms
!=
0
&&
_dataTick
+
maxOld_ms
<=
t
)
return
ifNoData
.
Get
();
var
v
=
parser
.
Parse
(
_text
);
if
(
_dataTick
+
showOld_ms
<=
t
)
{
{
return
new
Element
[]{
new
Element
(
"OSDD parse ERROR"
,
color
:
Color
.
Red
)};
bool
first
=
true
;
v
.
Select
(
x
=>
{
var
v
=
x
;
if
(
first
)
v
=
v
with
{
text
=
$"[
{
TimeShow
.
Show
((
t
-
_dataTick
)/
1000
)}
]
{
v
.
text
}
"
};
first
=
false
;
return
v
;
}).
ToArray
();
}
}
return
v
;
}
}
}
}
[
ModuleName
(
"i3status"
)]
[
ModuleName
(
"i3status"
)]
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment