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; 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.printf(" Hour count: %f\nHours & Minutes: %02d:%02d\n\n", hours, int(hours), minutes) total_hours += hours } else { // Noffin i guess fmt.printf("\n\n") } } fmt.printf("\nTOTAL\n\n") total_final_hour_fraction : f64 = total_hours - f64(int(total_hours)); 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) 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 } }