80 lines
1.9 KiB
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]
|
|
}
|