Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows custom sorting for termine yarpnarap #108

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 86 additions & 20 deletions termine/yarpnarp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,47 @@ import (
"fmt"
"os"
"sort"
"strings"
"text/tabwriter"
"time"

"github.com/nnev/website/data"
)

type OrderPriority = uint8

const (
Asc OrderPriority = iota
Desc
)

type ZusageOrderBy = uint8

const (
ZusageByNick ZusageOrderBy = iota
ZusageByKommt
ZusageByKommentar
ZusageByRegistered
)

type ZusageOrder struct {
by ZusageOrderBy
priority OrderPriority
}

var cmdYarpNarp = &Command{
UsageLine: "yarpnarp",
Short: "Zeige Zu- und Absagen für den Stammtisch",
Long: `Zeigt die Zu- und Absagen für den Stammtisch an`,
Flag: flag.NewFlagSet("clear", flag.ExitOnError),
Flag: flag.NewFlagSet("yarpnarp", flag.ExitOnError),
NeedsDB: true,
RegenWebsite: false,
}

var sortOrder string

func init() {
cmdYarpNarp.Flag.StringVar(&sortOrder, "sort", "-kommt,+registered", "Bestimmt die Sortierreihenfolge")
cmdYarpNarp.Run = RunYarpNarp
}

Expand All @@ -34,24 +59,32 @@ func (z Zusagen) Swap(i, j int) {
z[i], z[j] = z[j], z[i]
}

func (z Zusagen) Less(i, j int) bool {
if z[i].Kommt && !z[j].Kommt {
return true
} else if z[j].Kommt && !z[i].Kommt {
return false
}

// If one or both registered fields are NULL, just treat them as the zero
// time (so they sort before all other values)
if z[i].Registered.Time.Before(z[j].Registered.Time) {
return true
} else if z[j].Registered.Time.Before(z[i].Registered.Time) {
return false
}

// If one or both nick fields are NULL, just tream them as the empty string
if z[i].Nick.String < z[j].Nick.String {
return true
func (z Zusagen) Less(i, j int, key []ZusageOrder) bool {
for _, order := range key {
i_, j_ := i, j
if order.priority == Desc {
i_, j_ = j, i
}
switch order.by {
case ZusageByKommentar:
if z[i_].Kommentar < z[j_].Kommentar {
return true
}
case ZusageByKommt:
if !z[i_].Kommt && z[j_].Kommt {
return true
}
case ZusageByNick:
if z[i_].Nick.String < z[j_].Nick.String {
return true
}
case ZusageByRegistered:
if z[i_].Registered.Time.Before(z[j_].Registered.Time) {
return true
}
default:
panic("Invalid ZusageOrderBy field")
}
}

return false
Expand All @@ -75,6 +108,36 @@ func formatBool(b bool) string {
return "Nein"
}

func parseSortOrder(s string) []ZusageOrder {
elements := strings.Split(s, ",")
result := make([]ZusageOrder, len(elements))
for i, element := range elements {
result[i].priority = Asc

if element[0] == '-' {
result[i].priority = Desc
}
if element[0] == '+' || element[0] == '-' {
element = element[1:]
}

switch element {
case "nick":
result[i].by = ZusageByNick
case "kommentar":
result[i].by = ZusageByKommentar
case "kommt":
result[i].by = ZusageByKommt
case "registered":
result[i].by = ZusageByRegistered
default:
// FIXME: Probably not panic, because it is an expected error.
panic("Invalid sort order element")
}
}
return result
}

func maybeTruncate(s string, width int, truncate bool) string {
if !truncate {
return s
Expand All @@ -101,7 +164,10 @@ func RunYarpNarp() error {
return err
}

sort.Sort(zusagen)
order := parseSortOrder(sortOrder)
sort.Slice(zusagen, func(i, j int) bool {
return zusagen.Less(i, j, order)
})

width, trunc := TermWidth()

Expand Down