Erster Commit.
This commit is contained in:
commit
32b4c00942
|
|
@ -0,0 +1,3 @@
|
|||
module gittea.marcokittel.de/elio/eliotools/logger
|
||||
|
||||
go 1.24.4
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
Info(message string)
|
||||
Infof(format string, a ...any)
|
||||
Warning(message string)
|
||||
Critical(message string)
|
||||
Fatal(message string)
|
||||
}
|
||||
|
||||
type ML struct {
|
||||
}
|
||||
|
||||
func (m *ML) sendMsg(message string) {
|
||||
// Da die CSV Dateien RFC3339 nutzen, wechsel ich darauf im Log der
|
||||
// Konsistenz wegen.
|
||||
msg := "# " + time.Now().Format(time.RFC3339) + "\n* " + message
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
func (m *ML) sendMsgWithStack(message string) {
|
||||
msg := message
|
||||
stack := string(debug.Stack())
|
||||
msg += "\n\n### *** Stack ***\n\n\n >" + indentStacktrace(stack)
|
||||
msg += "\n________"
|
||||
m.sendMsg(msg)
|
||||
}
|
||||
|
||||
func (m *ML) Info(message string) {
|
||||
m.sendMsgWithStack("Info: " + message)
|
||||
}
|
||||
|
||||
func (m *ML) Infof(format string, a ...any) {
|
||||
msg := fmt.Sprintf(format, a)
|
||||
m.sendMsgWithStack("Info: " + msg)
|
||||
}
|
||||
|
||||
func (m *ML) Warning(message string) {
|
||||
m.sendMsgWithStack("Warning: " + message)
|
||||
}
|
||||
|
||||
func (m *ML) Critical(message string) {
|
||||
stack := string(debug.Stack())
|
||||
m.sendMsgWithStack("Critical: " + message + indentStacktrace(stack))
|
||||
}
|
||||
|
||||
func (m *ML) Fatal(message string) {
|
||||
m.sendMsgWithStack("Fatal" + message)
|
||||
panic(message)
|
||||
}
|
||||
func indentStacktrace(stack string) string {
|
||||
lines := strings.Split(stack, "\n")
|
||||
for i := 1; i < len(lines); i++ {
|
||||
lines[i] = " " + lines[i]
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func NewMarcoLogger() Logger {
|
||||
log := ML{}
|
||||
return &log
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module gittea.marcokittel.de/elio/eliotools/tools
|
||||
|
||||
go 1.24.4
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
func IsFilenameValid(filename string) bool {
|
||||
pattern := `^20[2-9][0-9]-(0[1-9]|1[0-2])-(0[0-9]|1[0-9]|2[0-9]|3[0-1])T(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]:[0-5][0-9])((\+00:00)|(\-00:00)|(\-0[3,9]:30)|(\-1[0-2]:00)|(-0[0-9]:00)|(\+0[0-9]:00)|(\+0[09,03,04,05,06]:30)|(\+10:30)|(\+1[0-4]:00)|(\+0[5,8]:45)|(\+12:45))-(CH|DE|EU|AT)-(stock|delivery).csv$`
|
||||
re := regexp.MustCompile(pattern)
|
||||
return re.MatchString(filename)
|
||||
}
|
||||
|
||||
func CheckDir(path string) (bool, error) {
|
||||
info, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return info.IsDir(), nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func RFC3339StringToTime(rfc3339str string) (time.Time, error) {
|
||||
const MINUS12STUNDEN = -43200
|
||||
const PLUS24STUNDEN = 50400
|
||||
t, err := time.Parse("2006-01-02T15:04:05-07:00", rfc3339str)
|
||||
if err != nil {
|
||||
happybirthday := time.Date(1981, time.March, 1, 4, 15, 0, 0, time.UTC)
|
||||
return happybirthday, err
|
||||
}
|
||||
|
||||
_, offset := t.Zone()
|
||||
if offset < MINUS12STUNDEN || offset > PLUS24STUNDEN {
|
||||
return time.Date(1981, time.March, 1, 4, 15, 0, 0, time.UTC), errors.New("timezone offset must be between -12:00 and +14:0")
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHello(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2023-11-09T15:02:17+00:00-CH-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+00:00-DE-delivery.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+00:00-EU-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+00:00-AT-stock.csv", valid: true},
|
||||
}
|
||||
|
||||
//"2023-11-09T15:02:17+00:00-CH-stock.csv"
|
||||
|
||||
for i, tc := range testcases {
|
||||
result := IsFilenameValid(tc.testcase)
|
||||
if result != tc.valid {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, tc.testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestValidTimeZonesWith30(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2023-11-09T15:02:17+03:30-EU-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+04:30-DE-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+05:30-DE-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+06:30-CH-delivery.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+09:30-CH-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+10:30-AT-stock.csv", valid: true},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result := IsFilenameValid(tc.testcase)
|
||||
if result != tc.valid {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, tc.testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidDateTime(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2025-11-29T23:02:17+03:30-EU-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+04:30-DE-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+05:30-DE-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+06:30-CH-delivery.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+09:30-CH-stock.csv", valid: true},
|
||||
{testcase: "2023-11-09T15:02:17+10:30-AT-delivery.csv", valid: true},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result := IsFilenameValid(tc.testcase)
|
||||
if result != tc.valid {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, tc.testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInValidTimeZonesWith30(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2023-11-09T15:02:17+02:30-EU-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:17+01:30-DE-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:17+23:30-DE-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:17+07:30-CH-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:17+08:30-CH-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:17+12:30-AT-stock.csv", valid: false},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result := IsFilenameValid(tc.testcase)
|
||||
if result != tc.valid {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, tc.testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInValidDateTimeWith(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2000-11-03T15:02:17+00:00-EU-stock.csv", valid: false},
|
||||
{testcase: "2026-11-03T15:60:17+00:00-EU-stock.csv", valid: false},
|
||||
{testcase: "2025-00-03T15:20:17+00:00-EU-stock.csv", valid: false},
|
||||
{testcase: "2100-01-03T23:59:17+00:00-EU-stock.csv", valid: false},
|
||||
{testcase: "2027-2-03T15:20:17+00:00-EU-stock.csv", valid: false},
|
||||
{testcase: "2023-11-09T15:02:51+00:01-AT-stock.csv", valid: false},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result := IsFilenameValid(tc.testcase)
|
||||
if result != tc.valid {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, tc.testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidRFC3339StringToTime(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
valid bool
|
||||
}{
|
||||
{testcase: "2000-11-03T15:02:17+00:00", valid: true},
|
||||
{testcase: "2026-11-03T15:02:17+03:30", valid: true},
|
||||
{testcase: "2026-12-03T23:02:17+05:30", valid: true},
|
||||
{testcase: "2026-11-03T15:02:17-12:00", valid: true},
|
||||
{testcase: "2026-11-03T23:59:17+14:00", valid: true},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result, err := RFC3339StringToTime(tc.testcase)
|
||||
if err != nil || tc.valid == false {
|
||||
t.Errorf("Testcase %d is not valid, but %s must be valid!", i, result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func TestInValidRFC3339StringToTime(t *testing.T) {
|
||||
testcases := []struct {
|
||||
testcase string
|
||||
invalid bool
|
||||
}{
|
||||
{testcase: "2026-13-03T23:02:17+05:30", invalid: true},
|
||||
{testcase: "2026-00-03T23:02:17+05:30", invalid: true},
|
||||
{testcase: "2026-03-03T23:02:17+99:30", invalid: true},
|
||||
{testcase: "2026-03-03T23:02:17+99:00", invalid: true},
|
||||
{testcase: "2026-03-03T23:02:17+16:00", invalid: true},
|
||||
}
|
||||
|
||||
for i, tc := range testcases {
|
||||
result, err := RFC3339StringToTime(tc.testcase)
|
||||
if err == nil && tc.invalid {
|
||||
t.Errorf("Testcase %d is valid, but %s must be invalid!", i, result.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue