aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSan Jacobs2025-06-06 04:18:45 +0200
committerSan Jacobs2025-06-06 04:18:45 +0200
commit479c4d2d6b96d3cdc82c5a7a0ac5ba7514d87e0c (patch)
tree80142e5330df1b09dfdaf13a6b8bbf8c641537df
parent05bd430377d0085095d9c78e5922642490e1baa3 (diff)
downloadbetter-report-479c4d2d6b96d3cdc82c5a7a0ac5ba7514d87e0c.tar.gz
better-report-479c4d2d6b96d3cdc82c5a7a0ac5ba7514d87e0c.tar.bz2
better-report-479c4d2d6b96d3cdc82c5a7a0ac5ba7514d87e0c.zip
Submitting a directory will cause a recursive search for all CSVs inside
-rwxr-xr-xmain.odin135
1 files changed, 103 insertions, 32 deletions
diff --git a/main.odin b/main.odin
index 2716171..fcaacb2 100755
--- a/main.odin
+++ b/main.odin
@@ -3,6 +3,7 @@ package main
import "core:fmt"
import "core:os"
import "core:path/filepath"
+import "core:sys/windows"
import "core:strings"
/*
@@ -10,12 +11,25 @@ TODO: If submitted path is a directory, traverse the tree to find all .CSVs
TODO: Move info that's all the same throughout the table into the info header
*/
-VERBOSE :: true
+VERBOSE :: false
PART_ONE :: #load("parts/start.html", string)
PART_TWO :: #load("parts/start2.html", string)
PART_END :: #load("parts/end.html", string)
+Device :: enum {
+ UNSET,
+ ZOOM,
+ SOUND_DEVICES,
+}
+
+Stages :: enum {
+ TITLE,
+ INFO,
+ HEADER,
+ BODY,
+}
+
Info_Line :: struct {
field : string,
entry : string,
@@ -32,41 +46,56 @@ Report :: struct {
}
main :: proc() {
+ when ODIN_OS == .Windows {
+ windows.SetConsoleOutputCP(windows.CODEPAGE.UTF8)
+ }
input_file_name : string
if len(os.args) < 2 {
- // Attempt to auto-detect CSVs, but filepath.glob is broken.
- // It doesn't return anything if you run the exe from a PATH folder.
-
- /* fmt.println("No file submitted. Using first CSV found.")
- glob_pattern := fmt.aprintf("{}\\*.*", os.get_current_directory())
- fmt.println(glob_pattern)
- csvs, _ := filepath.glob(glob_pattern)
- fmt.println(csvs)
- input_file_name = csvs[0] */
fmt.println("ERROR: No file submitted.")
return
} else {
- fmt.printf("Input CSV: {}\n", os.args[1])
+ fmt.printf("Input path: {}\n", os.args[1])
input_file_name = os.args[1]
}
- input_file_info, error := os.stat(input_file_name)
+
+ path_info, error := os.stat(input_file_name)
+
if error == os.ERROR_NONE {
- parsed, ok_parse := parse(input_file_info.fullpath)
- if !ok_parse {
- fmt.printf("Parse failed: {}\n", input_file_info.fullpath)
+
+ file_list : [dynamic]string
+ file_count := 0
+ if(path_info.is_dir) {
+ fmt.println("Directory submitted! Walking directory...\n")
+ fmt.printf("📁 {}\n", path_info.name)
+ walk_directory(path_info.fullpath, &file_count, &file_list, 1)
+ fmt.println("")
+ } else {
+ append(&file_list, strings.clone(path_info.fullpath))
+ }
+
+ fmt.println(file_list)
+
+ for file in file_list {
+ file_info, _ := os.stat(file)
+ parsed, ok_parse := parse(file_info.fullpath)
+ if !ok_parse {
+ fmt.printf("Parse failed: {}\n", file_info.fullpath)
+ continue
+ }
+ output_name := fmt.aprintf("{}_Knekt.html", file_info.fullpath[:len(file_info.fullpath)-4], allocator=context.temp_allocator)
+ render(parsed, output_name)
+ free_all(context.temp_allocator)
}
- output_name := fmt.aprintf("{}_Knekt.html", input_file_info.fullpath[:len(input_file_info.fullpath)-4])
- render(parsed, output_name)
} else {
- fmt.printf("Skipped: {}\n", input_file_name)
+ fmt.printf("ERROR could not get path info for: {}\n", input_file_name)
}
-
- free_all(context.temp_allocator)
}
+
+
parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) {
device := device
output : Report = {}
@@ -100,7 +129,10 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) {
line_number += 1
}
-
+ if device == .UNSET {
+ fmt.printf("ERROR: Unable to detect sound report type!\n")
+ return {}, false
+ }
@@ -136,7 +168,7 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) {
case .ZOOM:
- fmt.printf("Parsing [{}] as ZOOM report.\n", path)
+ fmt.printf("Parsing [{}] as ZOOM report, ", file_info.name)
// Getting title
if file_info.name[:8] == "F8n Pro_" {
@@ -146,7 +178,7 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) {
} else if file_info.name[:3] == "F8_" { // TODO: Verify this is what the original F8 does
output.title = file_info.name[4:len(file_info.name)-4]
}
- fmt.printf("Title: {}\n", output.title)
+ fmt.printf("titled \"{}\".\n", output.title)
line_index := 0
info_line_index := 0
@@ -322,18 +354,57 @@ render :: proc(report : Report, path : string) {
output_text := strings.to_string(builder)
os.write_entire_file(path, transmute([]u8)output_text)
+
+ fmt.printf("Output: {}\n", path)
}
-Device :: enum {
- UNSET,
- ZOOM,
- SOUND_DEVICES,
+
+
+indent_by :: proc(i : int) {
+ for x in 0..<i {
+ fmt.printf(" ")
+ }
}
-Stages :: enum {
- TITLE,
- INFO,
- HEADER,
- BODY,
+walk_directory :: proc(path : string, file_number : ^int, file_list : ^[dynamic]string, depth : int = 0) {
+ handle, ok := os.open(path)
+ if ok != os.ERROR_NONE {
+ indent_by(depth)
+ fmt.printf("ERROR opening dir: %s\n", path)
+ return
+ }
+ defer os.close(handle)
+
+ files, okr := os.read_dir(handle, -1)
+ if okr != os.ERROR_NONE {
+ indent_by(depth)
+ fmt.printf("ERROR reading dir: %s\n", path)
+ return
+ }
+ defer delete(files)
+
+
+ for file in files {
+
+ full_path := file.fullpath
+ defer delete(full_path)
+
+ if file.is_dir {
+ indent_by(depth)
+ fmt.printf("📁 %s\n", file.name)
+ walk_directory(full_path, file_number, file_list, depth+1) // Recurse
+
+ } else { // If file is actually a file
+
+ extension := strings.to_lower(filepath.ext(file.name))
+ defer delete(extension)
+ if(extension == ".csv"){
+ indent_by(depth)
+ fmt.printf("📄 %d %s\n", file_number^, file.name)
+ append(file_list, strings.clone(file.fullpath))
+ file_number^ += 1
+ }
+ }
+ }
} \ No newline at end of file