diff --git a/doc/soju.1.scd b/doc/soju.1.scd index e15ddc8..b48c608 100644 --- a/doc/soju.1.scd +++ b/doc/soju.1.scd @@ -186,6 +186,15 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just *network status* Show a list of saved networks and their current status. +*channel status* [options...] + Show a list of saved channels and their current status. + + Options: + + *-network* + Only show channels for the specified network. By default, only the + channels in the current network are displayed. + *channel update* [options...] Update the options of an existing channel. diff --git a/service.go b/service.go index 3b92af9..295dbd3 100644 --- a/service.go +++ b/service.go @@ -221,6 +221,11 @@ func init() { }, "channel": { children: serviceCommandSet{ + "status": { + usage: "[-network name]", + desc: "show a list of saved channels and their current status", + handle: handleServiceChannelStatus, + }, "update": { usage: " [-relay-detached ] [-reattach-on ] [-detach-after ] [-detach-on ]", desc: "update a channel", @@ -707,6 +712,64 @@ func handleUserDelete(dc *downstreamConn, params []string) error { return nil } +func handleServiceChannelStatus(dc *downstreamConn, params []string) error { + var defaultNetworkName string + if dc.network != nil { + defaultNetworkName = dc.network.GetName() + } + + fs := newFlagSet() + networkName := fs.String("network", defaultNetworkName, "") + + if err := fs.Parse(params); err != nil { + return err + } + + sendNetwork := func(net *network) { + for _, entry := range net.channels.innerMap { + ch := entry.value.(*Channel) + + var uch *upstreamChannel + if net.conn != nil { + uch = net.conn.channels.Value(ch.Name) + } + + name := ch.Name + if *networkName == "" { + name += "/" + net.GetName() + } + + var status string + if uch != nil { + status = "joined" + } else if net.conn != nil { + status = "parted" + } else { + status = "disconnected" + } + + if ch.Detached { + status += ", detached" + } + + s := fmt.Sprintf("%v [%v]", name, status) + sendServicePRIVMSG(dc, s) + } + } + + if *networkName == "" { + dc.user.forEachNetwork(sendNetwork) + } else { + net := dc.user.getNetwork(*networkName) + if net == nil { + return fmt.Errorf("unknown network %q", *networkName) + } + sendNetwork(net) + } + + return nil +} + type channelFlagSet struct { *flag.FlagSet RelayDetached, ReattachOn, DetachAfter, DetachOn *string