aboutsummaryrefslogtreecommitdiff
path: root/main.odin
diff options
context:
space:
mode:
authorSan Jacobs2025-09-14 04:58:08 +0200
committerSan Jacobs2025-09-14 04:58:08 +0200
commit0677448940089fca9f3d66b52145eef66962e449 (patch)
tree9aa6d58e460d359deddcd1560a3e17b866fc38b2 /main.odin
parent6aecd424625c4b2bad8a4cf56d06d3c645794341 (diff)
downloadstatics-0677448940089fca9f3d66b52145eef66962e449.tar.gz
statics-0677448940089fca9f3d66b52145eef66962e449.tar.bz2
statics-0677448940089fca9f3d66b52145eef66962e449.zip
Added filtering feature
Diffstat (limited to 'main.odin')
-rw-r--r--main.odin171
1 files changed, 165 insertions, 6 deletions
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