blog/core/models/comments/subscribers.go

80 lines
1.9 KiB
Go

package comments
import "strings"
// ListDBName is the path to the singleton mailing list manager.
const ListDBName = "comments/mailing-list"
// MailingList manages subscription data for all comment threads.
type MailingList struct {
Threads map[string]Subscription
}
// Subscription is the data for a single thread's subscribers.
type Subscription struct {
Emails map[string]bool
}
// LoadMailingList loads the mailing list, or initializes it if it doesn't exist.
func LoadMailingList() *MailingList {
m := &MailingList{
Threads: map[string]Subscription{},
}
DB.Get(ListDBName, &m)
return m
}
// Subscribe to a comment thread.
func (m *MailingList) Subscribe(thread, email string) error {
email = strings.ToLower(email)
t := m.initThread(thread)
t.Emails[email] = true
return DB.Commit(ListDBName, &m)
}
// List the subscribers for a thread.
func (m *MailingList) List(thread string) []string {
t := m.initThread(thread)
result := []string{}
for email := range t.Emails {
result = append(result, email)
}
return result
}
// Unsubscribe from a comment thread. Returns true if the removal was
// successful; false indicates the email was not subscribed.
func (m *MailingList) Unsubscribe(thread, email string) bool {
email = strings.ToLower(email)
t := m.initThread(thread)
if _, ok := t.Emails[email]; ok {
delete(t.Emails, email)
DB.Commit(ListDBName, &m)
return true
}
return false
}
// UnsubscribeAll removes the email from all mailing lists.
func (m *MailingList) UnsubscribeAll(email string) bool {
var any bool
email = strings.ToLower(email)
for thread := range m.Threads {
if m.Unsubscribe(thread, email) {
any = true
}
}
return any
}
// initialize a thread structure.
func (m *MailingList) initThread(thread string) Subscription {
if _, ok := m.Threads[thread]; !ok {
m.Threads[thread] = Subscription{
Emails: map[string]bool{},
}
}
return m.Threads[thread]
}