Skip to content

Commit

Permalink
feat: allow unmuting proposals (#94)
Browse files Browse the repository at this point in the history
* feat: allow unmuting proposals

* chore: add OTLP tracing configuration
  • Loading branch information
freak12techno committed May 17, 2024
1 parent 96ce288 commit 5cb4556
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ To have fancy commands auto-suggestion, go to @BotFather again, select your bot
and paste the following:
```
proposals - List proposals and wallets' votes on them
proposals_mute - Mutes a proposal
proposals_mute - Mutes notifications on a chain/proposal
proposals_unmute - Unmutes notifications on a chain/proposal
proposals_mutes - List active proposal mutes
tally - Show the tally for proposals that are in voting period
params - Show chains params related to governance
Expand Down
15 changes: 15 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ level = "trace"
# solition, like ELK. Defaults to false.
json = false

# Tracing configuration.
# If enabled, all reports traces are going to be sent to a remote storage
# via OpenTelemetry HTTP protocol.
# You probably don't need this, so feel free to omit this whole block.
[tracing]
# Whether tracing reporting is enabled. Defaults to false.
enabled = false
# OpenTelemetry HTTP host to send traces to
open-telemetry-http-host = "localhost:4123"
# If true, then requests would be done via HTTP rather than HTTPS. Defaults to true.
open-telemetry-http-insecure = true
# OTLP login and password, if needed.
open-telemetry-http-user = "admin"
open-telemetry-http-password = "password"

# Per-chain config. There can be multiple chains.
[[chains]]
# Chain name, used internally. Required. Should be unique.
Expand Down
6 changes: 6 additions & 0 deletions pkg/mutes/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,9 @@ func (m *Manager) AddMute(mute *Mute) {
m.Mutes.AddMute(mute)
m.Save()
}

func (m *Manager) DeleteMute(mute *Mute) bool {
found := m.Mutes.DeleteMute(mute)
m.Save()
return found
}
16 changes: 15 additions & 1 deletion pkg/mutes/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func TestMuteManagerSaveWithoutError(t *testing.T) {
assert.Empty(t, manager.Mutes.Mutes)
}

func TestMuteManagerAddMuteIsMuted(t *testing.T) {
func TestMuteManagerAddAndDeleteMuteIsMuted(t *testing.T) {
t.Parallel()

log := logger.GetNopLogger()
Expand All @@ -120,6 +120,20 @@ func TestMuteManagerAddMuteIsMuted(t *testing.T) {
Chain: &types.Chain{Name: "chain2"},
Proposal: types.Proposal{ID: "proposal"},
}))

deleted := manager.DeleteMute(&Mute{
Chain: "chain",
})
assert.True(t, deleted)

assert.False(t, manager.IsEntryMuted(events.VotedEvent{
Chain: &types.Chain{Name: "chain"},
Proposal: types.Proposal{ID: "proposal"},
}))
assert.False(t, manager.IsEntryMuted(events.VotedEvent{
Chain: &types.Chain{Name: "chain2"},
Proposal: types.Proposal{ID: "proposal"},
}))
}

func TestMuteManagerIsMutedNoPath(t *testing.T) {
Expand Down
17 changes: 17 additions & 0 deletions pkg/mutes/mutes.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,20 @@ func (m *Mutes) AddMute(mute *Mute) {
return !m.IsExpired()
})
}

func (m *Mutes) DeleteMute(mute *Mute) bool {
for index, existingMute := range m.Mutes {
if existingMute.LabelsEqual(mute) {
m.Mutes = append(m.Mutes[:index], m.Mutes[index+1:]...)
m.Mutes = utils.Filter(m.Mutes, func(m *Mute) bool {
return !m.IsExpired()
})
return true
}
}

m.Mutes = utils.Filter(m.Mutes, func(m *Mute) bool {
return !m.IsExpired()
})
return false
}
31 changes: 31 additions & 0 deletions pkg/mutes/mutes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,34 @@ func TestMutesAddsMuteOverride(t *testing.T) {
assert.Equal(t, "newcomment", mutes.Mutes[0].Comment)
assert.Equal(t, newExpireTime, mutes.Mutes[0].Expires)
}

func TestMutesDeleteMuteNotExisting(t *testing.T) {
t.Parallel()

mutes := Mutes{
Mutes: []*Mute{
{Chain: "chain1", Expires: time.Now().Add(time.Hour)},
},
}

deleted := mutes.DeleteMute(&Mute{Chain: "chain2"})
assert.False(t, deleted)
assert.Len(t, mutes.Mutes, 1)
}

func TestMutesDeleteMuteExisting(t *testing.T) {
t.Parallel()

mutes := Mutes{
Mutes: []*Mute{
{Chain: "chain2", ProposalID: "proposal1", Expires: time.Now().Add(time.Hour)},
{Chain: "chain1", ProposalID: "proposal2", Expires: time.Now().Add(time.Hour)},
{Chain: "chain1", ProposalID: "proposal1", Expires: time.Now().Add(time.Hour)},
{Chain: "chain2", ProposalID: "proposal2", Expires: time.Now().Add(time.Hour)},
},
}

deleted := mutes.DeleteMute(&Mute{Chain: "chain1", ProposalID: "proposal1"})
assert.True(t, deleted)
assert.Len(t, mutes.Mutes, 3)
}
29 changes: 29 additions & 0 deletions pkg/reporters/telegram/delete_mute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package telegram

import (
tele "gopkg.in/telebot.v3"
)

func (reporter *Reporter) HandleDeleteMute(c tele.Context) error {
reporter.Logger.Info().
Str("sender", c.Sender().Username).
Str("text", c.Text()).
Msg("Got delete mute query")

mute, err := ParseMuteDeleteOptions(c.Text(), c)
if err != "" {
return c.Reply("Error deleting mute: " + err)
}

if found := reporter.MutesManager.DeleteMute(mute); !found {
return c.Reply("Could not find the mute to delete!")
}

templateRendered, renderErr := reporter.TemplatesManager.Render("mute_deleted", mute)
if renderErr != nil {
reporter.Logger.Error().Err(renderErr).Msg("Error rendering template")
return reporter.BotReply(c, "Error rendering template")
}

return reporter.BotReply(c, templateRendered)
}
32 changes: 32 additions & 0 deletions pkg/reporters/telegram/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (reporter *Reporter) Init() error {
bot.Handle("/start", reporter.HandleHelp)
bot.Handle("/help", reporter.HandleHelp)
bot.Handle("/proposals_mute", reporter.HandleAddMute)
bot.Handle("/proposals_unmute", reporter.HandleDeleteMute)
bot.Handle("/proposals_mutes", reporter.HandleListMutes)
bot.Handle("/proposals", reporter.HandleProposals)
bot.Handle("/tally", reporter.HandleTally)
Expand Down Expand Up @@ -199,3 +200,34 @@ func ParseMuteOptions(query string, c tele.Context) (*mutes.Mute, string) {

return mute, ""
}

func ParseMuteDeleteOptions(query string, c tele.Context) (*mutes.Mute, string) {
// we only construct mute with chain/proposal to compare, no need to take care
// about the expiration/comment
mute := &mutes.Mute{
Chain: "",
ProposalID: "",
Expires: time.Now(),
Comment: "",
}

for index, arg := range c.Args() {
argSplit := strings.SplitN(arg, "=", 2)
if len(argSplit) < 2 {
return nil, fmt.Sprintf(
"Invalid param at position %d: expected an expression like \"[chain=cosmos]\", but got %s",
index+1,
arg,
)
}

switch argSplit[0] {
case "chain":
mute.Chain = argSplit[1]
case "proposal":
mute.ProposalID = argSplit[1]
}
}

return mute, ""
}
11 changes: 11 additions & 0 deletions templates/telegram/mute_deleted.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Deleted mute with the following params:
{{- if .Chain }}
<strong>Chain:</strong> {{ .Chain }}
{{- else }}
<strong>Chain:</strong> all chains
{{- end }}
{{- if .ProposalID }}
<strong>Proposal ID:</strong> {{ .ProposalID }}
{{- else }}
<strong>Proposal ID:</strong> all proposals
{{- end }}

0 comments on commit 5cb4556

Please sign in to comment.