From 0677448940089fca9f3d66b52145eef66962e449 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sun, 14 Sep 2025 04:58:08 +0200 Subject: Added filtering feature --- main.odin | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 6 deletions(-) (limited to 'main.odin') diff --git a/main.odin b/main.odin index da72be7..7f05efe 100644 --- a/main.odin +++ b/main.odin @@ -2,29 +2,148 @@ package main import "core:fmt" import "core:os" +import "core:strings" +import "core:strconv" dayrate : f64 = 3500 +Arg_Type :: enum { + NONE, + FROM, + TO, + IN, +} +Arg_Flags :: bit_set[Arg_Type] + +Range_Flags_Enum :: enum { + YEAR, + MONTH, + DAY, + HOUR, + MINUTE, +} +Range_Flags :: bit_set[Range_Flags_Enum] + +Filter :: struct { + ranges : Range_Flags, + time : Moment, +} + main :: proc() { arg_count := len(os.args)-1 + filters : Arg_Flags = {} + parsing : Arg_Type = .NONE + + verbose := false + + to_filter : Filter + from_filter : Filter + in_filter : Filter + in_filter_out : Filter + + file_index_buffer : [dynamic]int + + for &arg, i in os.args { + switch parsing { + case .NONE: + lower := strings.to_lower(arg, context.temp_allocator) + if lower[max(0, len(lower)-4):len(lower)] == ".ics" { + append(&file_index_buffer, i) + } else { + switch lower { + case "-t": + parsing = .TO + case "-f": + parsing = .FROM + case "-i": + parsing = .IN + case "-v": + verbose = true + case "-h": + fmt.println("statICS by Sander J. Skjegstad\n") + + fmt.println("Usage:") + fmt.println("statics path/to/file.ics path/to/another_file.ics [FLAGS]") + + fmt.println("\nFlags:") + fmt.println("\t-t To: Filter up to and NOT including a specific time.") + fmt.println("\t-f From: Filter from and including a specific time.") + fmt.println("\t-i In: Filter to inside a specific year, month, etc.") + fmt.println("\t-v Verbose: Prints more info.") + fmt.println("\t-h Help: Show this screen.") + + fmt.println("\nFilter syntax:") + fmt.println("Filters currently only filter based on the event start time.") + fmt.println("Specify only as much as you want to filter by.") + fmt.println("YYYY-MM-DD-Hr-Mn") + fmt.println("\n-t 2015-12-31-12-45 will not count anything from that point and out.") + fmt.println("-i 2018-12 will only count things within December of 2018.") + os.exit(0) + } + } + case .FROM: + parse_to_filter(&arg, &from_filter) + filters |= {.FROM} + fmt.println("FROM filter set up from", momentToString(from_filter.time)) + parsing = .NONE + case .TO: + parse_to_filter(&arg, &to_filter) + filters |= {.TO} + fmt.println("TO filter set up to", momentToString(to_filter.time)) + filter_maxx(&to_filter) + parsing = .NONE + case .IN: + parse_to_filter(&arg, &in_filter) + in_filter_out = in_filter + filter_maxx(&in_filter_out) + filters |= {.IN} + fmt.println("IN filter set up from", momentToString(in_filter.time), "to", momentToString(in_filter_out.time)) + parsing = .NONE + + } + } + total_hours : f64 = 0; - for i in 1..=arg_count { + + fmt.println() + + for i in file_index_buffer { fmt.printf("%d: ", i) + fmt.println(os.args[i]) timeblocks, ok := importICS(os.args[i]) if ok { hours : f64 = 0 for each_block in timeblocks { + if verbose do fmt.println("Timeblock:", timeblockToString(each_block)) + pass := true + if .FROM in filters { + pass_from := greatEq(each_block.start, from_filter.time) + if verbose do if !pass_from do fmt.println(" FILTERED! By From filter") + pass &= pass_from + } + if .TO in filters { + pass_to := lessEq(each_block.start, to_filter.time) + if verbose do if !pass_to do fmt.println(" FILTERED! By To filter") + pass &= pass_to + } + if .IN in filters { + pass_in := lessEq(in_filter.time, each_block.start) && lessEq(each_block.start, in_filter_out.time) + if verbose do if !pass_in do fmt.println(" FILTERED! By In filter: ") + pass &= pass_in + } + + if !pass do continue + hours += f64(hourcount(each_block)) } minutes := int(f64(hours-f64(int(hours)))*60.0) - fmt.println(os.args[i]) - fmt.printf(" Hour count: %f\nHours & Minutes: %02d:%02d\n\n", - hours, int(hours), minutes) + fmt.printf(" Hour count: %f\nHours & Minutes: %02d:%02d\n\n", + hours, int(hours), minutes) total_hours += hours } else { // Noffin i guess @@ -38,8 +157,48 @@ main :: proc() { total_minutes := int(total_final_hour_fraction*60.0) - fmt.printf(" Hour count: %f\nHours & Minutes: %02d:%02d\n", - total_hours, int(total_hours), total_minutes) + fmt.printf(" Hour count: %f\nHours & Minutes: %02d:%02d\n", + total_hours, int(total_hours), total_minutes) return } + + +parse_to_filter :: proc(input : ^string, filter : ^Filter) { + i : int = 0 + ok : bool + for substring in strings.split_iterator(input, "-") { + switch i { + case 0: + filter.time.year, ok = strconv.parse_int(substring) + if !ok {fmt.eprintln("ERROR: Failed to parse year:", substring)} + filter.ranges |= {.YEAR} + case 1: + filter.time.month, ok = strconv.parse_int(substring) + if !ok {fmt.eprintln("ERROR: Failed to parse month:", substring)} + filter.ranges |= {.MONTH} + case 2: + filter.time.day, ok = strconv.parse_int(substring) + if !ok {fmt.eprintln("ERROR: Failed to parse day:", substring)} + filter.ranges |= {.DAY} + case 3: + filter.time.hours, ok = strconv.parse_int(substring) + if !ok {fmt.eprintln("ERROR: Failed to parse hours:", substring)} + filter.ranges |= {.HOUR} + case 4: + filter.time.minutes, ok = strconv.parse_int(substring) + if !ok {fmt.eprintln("ERROR: Failed to parse minutes:", substring)} + filter.ranges |= {.MINUTE} + } + i += 1 + if !ok do os.exit(1) + } +} + +filter_maxx :: proc(filter : ^Filter) { + // Super evil retarded bad hack, but it works! + if .MONTH not_in filter.ranges { filter.time.month = 99 } + if .DAY not_in filter.ranges { filter.time.day = 99 } + if .HOUR not_in filter.ranges { filter.time.hours = 99 } + if .MINUTE not_in filter.ranges { filter.time.minutes = 99 } +} \ No newline at end of file -- cgit v1.2.1