Added unsubscribe, help context
This commit is contained in:
parent
17ff7124df
commit
9512fcb206
144
commands.go
144
commands.go
|
@ -13,8 +13,10 @@ import (
|
|||
)
|
||||
|
||||
type command struct {
|
||||
Match *regexp.Regexp
|
||||
Handle func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool
|
||||
Help string
|
||||
Description string
|
||||
Match *regexp.Regexp
|
||||
Handle func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool
|
||||
}
|
||||
|
||||
var guestUserRegex = regexp.MustCompile("^Guest[0-9]+_*$")
|
||||
|
@ -26,9 +28,20 @@ func isNickAllowed(nick string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func filterEntriesForChannel(bot *hbot.Bot, message *hbot.Message, entries []*channelEntry) (result []*channelEntry) {
|
||||
for _, e := range entries {
|
||||
if e.ApiEndpoint != "" && (message.To == bot.Nick || e.Channel == message.To) {
|
||||
result = append(result, e)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var commands = []command{
|
||||
{
|
||||
Match: regexp.MustCompile("^\\.(status|shares)[ \\t]*"),
|
||||
Help: ".status",
|
||||
Description: "Displays your pool and share status across all subscriptions to your nick",
|
||||
Match: regexp.MustCompile("(?i)^\\.(status|shares)[ \t]*"),
|
||||
Handle: func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool {
|
||||
subs := db.GetByNick(message.Name)
|
||||
if len(subs) == 0 {
|
||||
|
@ -51,52 +64,50 @@ var commands = []command{
|
|||
|
||||
var hasResults bool
|
||||
var results []*result
|
||||
for i := range entries {
|
||||
e := entries[i]
|
||||
if e.ApiEndpoint != "" && (message.To == bot.Nick || e.Channel == message.To) {
|
||||
func() {
|
||||
e.ChainLock.RLock()
|
||||
defer e.ChainLock.RUnlock()
|
||||
|
||||
var tr []*result
|
||||
for _, sub := range subs {
|
||||
var r result
|
||||
r.Tip = e.Tip
|
||||
r.Endpoint = e.ApiEndpoint
|
||||
r.Address = sub.Address
|
||||
r.Consensus = e.Consensus
|
||||
for _, e := range filterEntriesForChannel(bot, message, entries) {
|
||||
func(e *channelEntry) {
|
||||
e.ChainLock.RLock()
|
||||
defer e.ChainLock.RUnlock()
|
||||
|
||||
r.SharesPosition = NewPositionChart(30, uint64(e.Tip.WindowDepth))
|
||||
r.UnclesPosition = NewPositionChart(30, uint64(e.Tip.WindowDepth))
|
||||
tr = append(tr, &r)
|
||||
}
|
||||
var tr []*result
|
||||
for _, sub := range subs {
|
||||
var r result
|
||||
r.Tip = e.Tip
|
||||
r.Endpoint = e.ApiEndpoint
|
||||
r.Address = sub.Address
|
||||
r.Consensus = e.Consensus
|
||||
|
||||
e.IterateWindow(func(b *index.SideBlock, weight types.Difficulty) {
|
||||
for _, r := range tr {
|
||||
r.TotalWeight = r.TotalWeight.Add(weight)
|
||||
if b.MinerAddress.Compare(r.Address) == 0 {
|
||||
r.MinerId = b.Miner
|
||||
r.YourWeight = r.YourWeight.Add(weight)
|
||||
if b.IsUncle() {
|
||||
r.UnclesPosition.Add(int(e.Tip.SideHeight-b.SideHeight), 1)
|
||||
r.UncleCount++
|
||||
} else {
|
||||
r.SharesPosition.Add(int(e.Tip.SideHeight-b.SideHeight), 1)
|
||||
r.ShareCount++
|
||||
}
|
||||
r.SharesPosition = NewPositionChart(30, uint64(e.Tip.WindowDepth))
|
||||
r.UnclesPosition = NewPositionChart(30, uint64(e.Tip.WindowDepth))
|
||||
tr = append(tr, &r)
|
||||
}
|
||||
|
||||
e.IterateWindow(func(b *index.SideBlock, weight types.Difficulty) {
|
||||
for _, r := range tr {
|
||||
r.TotalWeight = r.TotalWeight.Add(weight)
|
||||
if b.MinerAddress.Compare(r.Address) == 0 {
|
||||
r.MinerId = b.Miner
|
||||
r.YourWeight = r.YourWeight.Add(weight)
|
||||
if b.IsUncle() {
|
||||
r.UnclesPosition.Add(int(e.Tip.SideHeight-b.SideHeight), 1)
|
||||
r.UncleCount++
|
||||
} else {
|
||||
r.SharesPosition.Add(int(e.Tip.SideHeight-b.SideHeight), 1)
|
||||
r.ShareCount++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for _, r := range tr {
|
||||
if r.ShareCount > 0 || r.UncleCount > 0 {
|
||||
results = append(results, r)
|
||||
hasResults = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}()
|
||||
}
|
||||
for _, r := range tr {
|
||||
if r.ShareCount > 0 || r.UncleCount > 0 {
|
||||
results = append(results, r)
|
||||
hasResults = true
|
||||
}
|
||||
}
|
||||
|
||||
}(e)
|
||||
}
|
||||
|
||||
if !hasResults {
|
||||
|
@ -123,7 +134,9 @@ var commands = []command{
|
|||
},
|
||||
|
||||
{
|
||||
Match: regexp.MustCompile("^\\.(sub|subscribe)[ \\t]+(4[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+)[ \\t]*"),
|
||||
Help: ".subscribe MONERO_ADDRESS",
|
||||
Description: "Subscribes your nick, while online, to shares and payouts specified by MONERO_ADDRESS. You can have multiple subscriptions.",
|
||||
Match: regexp.MustCompile("(?i)^\\.(sub|subscribe)[ \t]+(4[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+)[ \t]*"),
|
||||
Handle: func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool {
|
||||
if err := isNickAllowed(message.Name); err != nil {
|
||||
bot.Msg(replyTo, fmt.Sprintf("Cannot subscribe: %s", err))
|
||||
|
@ -142,6 +155,9 @@ var commands = []command{
|
|||
}); err == nil {
|
||||
bot.Msg(replyTo, fmt.Sprintf("Subscribed your nick to shares found by %s%s%s while you are online. You can private message this bot for any commands instead of using public channels.", FormatItalic, utils.Shorten(addr.ToBase58(), 10), FormatReset))
|
||||
for _, e := range entries {
|
||||
if e.ApiEndpoint == "" {
|
||||
continue
|
||||
}
|
||||
func() {
|
||||
e.ChainLock.RLock()
|
||||
defer e.ChainLock.RUnlock()
|
||||
|
@ -169,4 +185,46 @@ var commands = []command{
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
Help: ".unsubscribe MONERO_ADDRESS",
|
||||
Description: "Unsubscribes your nick from shares and payouts specified by MONERO_ADDRESS.",
|
||||
Match: regexp.MustCompile("(?i)^\\.(unsub|unsubscribe)[ \t]+(4[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+)[ \t]*"),
|
||||
Handle: func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool {
|
||||
addr := address.FromBase58(matches[2])
|
||||
if addr == nil {
|
||||
bot.Msg(replyTo, "Cannot unsubscribe: Invalid Monero address")
|
||||
return true
|
||||
}
|
||||
|
||||
sub := &Subscription{
|
||||
Address: addr,
|
||||
Nick: message.Name,
|
||||
}
|
||||
|
||||
if err := db.Unsubscribe(sub); err != nil {
|
||||
bot.Msg(replyTo, fmt.Sprintf("Cannot unsubscribe: %s", err))
|
||||
return true
|
||||
} else {
|
||||
bot.Msg(replyTo, fmt.Sprintf("Unsubscribed your nick from shares found by %s%s%s", FormatItalic, utils.Shorten(addr.ToBase58(), 10), FormatReset))
|
||||
return true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
Help: ".unsubscribe",
|
||||
Description: "Unsubscribes from all subscriptions tied to your nick",
|
||||
//fallback unsubscribe for everything
|
||||
Match: regexp.MustCompile("(?i)^[.!]?(unsub|unsubscribe)[ \t]*"),
|
||||
Handle: func(db *DB, entries []*channelEntry, bot *hbot.Bot, message *hbot.Message, replyTo string, matches ...string) bool {
|
||||
removed := 0
|
||||
|
||||
for _, sub := range db.GetByNick(message.Name) {
|
||||
db.Unsubscribe(sub)
|
||||
removed++
|
||||
}
|
||||
|
||||
bot.Msg(replyTo, fmt.Sprintf("Unsubscribed your nick from %d subscriptions.", removed))
|
||||
return true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
59
db.go
59
db.go
|
@ -82,6 +82,65 @@ func (db *DB) GetByAddress(a *address.Address) (result []*Subscription) {
|
|||
return result
|
||||
}
|
||||
|
||||
func (db *DB) Unsubscribe(sub *Subscription) error {
|
||||
|
||||
if err := db.db.Update(func(tx *bolt.Tx) error {
|
||||
|
||||
b1 := tx.Bucket(refByAddr)
|
||||
var nicks []string
|
||||
if k := b1.Get([]byte(sub.Address.ToBase58())); k != nil {
|
||||
if err := json.Unmarshal(k, &nicks); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if i := slices.Index(nicks, strings.ToLower(sub.Nick)); i != -1 {
|
||||
nicks = slices.Delete(nicks, i, i+1)
|
||||
if len(nicks) == 0 {
|
||||
if err := b1.Delete([]byte(sub.Address.ToBase58())); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if buf, err := json.Marshal(nicks); err != nil {
|
||||
return err
|
||||
} else if err = b1.Put([]byte(sub.Address.ToBase58()), buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b2 := tx.Bucket(refByNick)
|
||||
var addresses []*address.Address
|
||||
if k := b2.Get([]byte(strings.ToLower(sub.Nick))); k != nil {
|
||||
if err := json.Unmarshal(k, &addresses); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if i := slices.IndexFunc(addresses, func(a *address.Address) bool {
|
||||
return a.Compare(sub.Address) == 0
|
||||
}); i != -1 {
|
||||
addresses = slices.Delete(addresses, i, i+1)
|
||||
|
||||
if len(addresses) == 0 {
|
||||
if err := b2.Delete([]byte(strings.ToLower(sub.Nick))); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if buf, err := json.Marshal(addresses); err != nil {
|
||||
return err
|
||||
} else if err = b2.Put([]byte(strings.ToLower(sub.Nick)), buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Printf("[DB] bolt error: %s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DB) Store(sub *Subscription) error {
|
||||
|
||||
if err := db.db.Update(func(tx *bolt.Tx) error {
|
||||
|
|
Loading…
Reference in a new issue