mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 20:09:41 +01:00
Merge pull request #811 from slingamn/history_nits.4
tweaks to persistent history
This commit is contained in:
commit
ec1a718275
@ -113,8 +113,8 @@ func (channel *Channel) IsLoaded() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) resizeHistory(config *Config) {
|
func (channel *Channel) resizeHistory(config *Config) {
|
||||||
_, ephemeral, _ := channel.historyStatus(config)
|
status, _ := channel.historyStatus(config)
|
||||||
if ephemeral {
|
if status == HistoryEphemeral {
|
||||||
channel.history.Resize(config.History.ChannelLength, config.History.AutoresizeWindow)
|
channel.history.Resize(config.History.ChannelLength, config.History.AutoresizeWindow)
|
||||||
} else {
|
} else {
|
||||||
channel.history.Resize(0, 0)
|
channel.history.Resize(0, 0)
|
||||||
@ -588,9 +588,9 @@ func (channel *Channel) IsEmpty() bool {
|
|||||||
|
|
||||||
// figure out where history is being stored: persistent, ephemeral, or neither
|
// figure out where history is being stored: persistent, ephemeral, or neither
|
||||||
// target is only needed if we're doing persistent history
|
// target is only needed if we're doing persistent history
|
||||||
func (channel *Channel) historyStatus(config *Config) (persistent, ephemeral bool, target string) {
|
func (channel *Channel) historyStatus(config *Config) (status HistoryStatus, target string) {
|
||||||
if !config.History.Persistent.Enabled {
|
if !config.History.Enabled {
|
||||||
return false, config.History.Enabled, ""
|
return HistoryDisabled, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
@ -599,18 +599,17 @@ func (channel *Channel) historyStatus(config *Config) (persistent, ephemeral boo
|
|||||||
registered := channel.registeredFounder != ""
|
registered := channel.registeredFounder != ""
|
||||||
channel.stateMutex.RUnlock()
|
channel.stateMutex.RUnlock()
|
||||||
|
|
||||||
historyStatus = historyEnabled(config.History.Persistent.RegisteredChannels, historyStatus)
|
|
||||||
|
|
||||||
// ephemeral history: either the channel owner explicitly set the ephemeral preference,
|
// ephemeral history: either the channel owner explicitly set the ephemeral preference,
|
||||||
// or persistent history is disabled for unregistered channels
|
// or persistent history is disabled for unregistered channels
|
||||||
if registered {
|
if registered {
|
||||||
ephemeral = (historyStatus == HistoryEphemeral)
|
return historyEnabled(config.History.Persistent.RegisteredChannels, historyStatus), target
|
||||||
persistent = (historyStatus == HistoryPersistent)
|
|
||||||
} else {
|
} else {
|
||||||
ephemeral = config.History.Enabled && !config.History.Persistent.UnregisteredChannels
|
if config.History.Persistent.UnregisteredChannels {
|
||||||
persistent = config.History.Persistent.UnregisteredChannels
|
return HistoryPersistent, target
|
||||||
|
} else {
|
||||||
|
return HistoryEphemeral, target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) AddHistoryItem(item history.Item) (err error) {
|
func (channel *Channel) AddHistoryItem(item history.Item) (err error) {
|
||||||
@ -618,14 +617,13 @@ func (channel *Channel) AddHistoryItem(item history.Item) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
persistent, ephemeral, target := channel.historyStatus(channel.server.Config())
|
status, target := channel.historyStatus(channel.server.Config())
|
||||||
if ephemeral {
|
if status == HistoryPersistent {
|
||||||
|
err = channel.server.historyDB.AddChannelItem(target, item)
|
||||||
|
} else if status == HistoryEphemeral {
|
||||||
channel.history.Add(item)
|
channel.history.Add(item)
|
||||||
}
|
}
|
||||||
if persistent {
|
return
|
||||||
return channel.server.historyDB.AddChannelItem(target, item)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join joins the given client to this channel (if they can be joined).
|
// Join joins the given client to this channel (if they can be joined).
|
||||||
|
@ -354,8 +354,8 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) resizeHistory(config *Config) {
|
func (client *Client) resizeHistory(config *Config) {
|
||||||
_, ephemeral, _ := client.historyStatus(config)
|
status, _ := client.historyStatus(config)
|
||||||
if ephemeral {
|
if status == HistoryEphemeral {
|
||||||
client.history.Resize(config.History.ClientLength, config.History.AutoresizeWindow)
|
client.history.Resize(config.History.ClientLength, config.History.AutoresizeWindow)
|
||||||
} else {
|
} else {
|
||||||
client.history.Resize(0, 0)
|
client.history.Resize(0, 0)
|
||||||
@ -749,16 +749,16 @@ func (session *Session) playResume() {
|
|||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
friends.Add(member)
|
friends.Add(member)
|
||||||
}
|
}
|
||||||
_, ephemeral, _ := channel.historyStatus(config)
|
status, _ := channel.historyStatus(config)
|
||||||
if ephemeral {
|
if status == HistoryEphemeral {
|
||||||
lastDiscarded := channel.history.LastDiscarded()
|
lastDiscarded := channel.history.LastDiscarded()
|
||||||
if oldestLostMessage.Before(lastDiscarded) {
|
if oldestLostMessage.Before(lastDiscarded) {
|
||||||
oldestLostMessage = lastDiscarded
|
oldestLostMessage = lastDiscarded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, cEphemeral, _ := client.historyStatus(config)
|
cHistoryStatus, _ := client.historyStatus(config)
|
||||||
if cEphemeral {
|
if cHistoryStatus == HistoryEphemeral {
|
||||||
lastDiscarded := client.history.LastDiscarded()
|
lastDiscarded := client.history.LastDiscarded()
|
||||||
if oldestLostMessage.Before(lastDiscarded) {
|
if oldestLostMessage.Before(lastDiscarded) {
|
||||||
oldestLostMessage = lastDiscarded
|
oldestLostMessage = lastDiscarded
|
||||||
@ -1551,29 +1551,21 @@ func (client *Client) attemptAutoOper(session *Session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) historyStatus(config *Config) (persistent, ephemeral bool, target string) {
|
func (client *Client) historyStatus(config *Config) (status HistoryStatus, target string) {
|
||||||
if !config.History.Enabled {
|
if !config.History.Enabled {
|
||||||
return
|
return HistoryDisabled, ""
|
||||||
} else if !config.History.Persistent.Enabled {
|
|
||||||
ephemeral = true
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
alwaysOn := client.alwaysOn
|
loggedIn := client.account != ""
|
||||||
historyStatus := client.accountSettings.DMHistory
|
historyStatus := client.accountSettings.DMHistory
|
||||||
target = client.nickCasefolded
|
target = client.nickCasefolded
|
||||||
client.stateMutex.RUnlock()
|
client.stateMutex.RUnlock()
|
||||||
|
|
||||||
if !alwaysOn {
|
if !loggedIn {
|
||||||
ephemeral = true
|
return HistoryEphemeral, ""
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return historyEnabled(config.History.Persistent.DirectMessages, historyStatus), target
|
||||||
historyStatus = historyEnabled(config.History.Persistent.DirectMessages, historyStatus)
|
|
||||||
ephemeral = (historyStatus == HistoryEphemeral)
|
|
||||||
persistent = (historyStatus == HistoryPersistent)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are bit flags indicating what part of the client status is "dirty"
|
// these are bit flags indicating what part of the client status is "dirty"
|
||||||
|
@ -185,25 +185,40 @@ func historyStatusToString(status HistoryStatus) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX you must have already checked History.Enabled before calling this
|
||||||
func historyEnabled(serverSetting PersistentStatus, localSetting HistoryStatus) (result HistoryStatus) {
|
func historyEnabled(serverSetting PersistentStatus, localSetting HistoryStatus) (result HistoryStatus) {
|
||||||
if serverSetting == PersistentDisabled {
|
switch serverSetting {
|
||||||
return HistoryDisabled
|
case PersistentMandatory:
|
||||||
} else if serverSetting == PersistentMandatory {
|
|
||||||
return HistoryPersistent
|
return HistoryPersistent
|
||||||
} else if serverSetting == PersistentOptOut {
|
case PersistentOptOut:
|
||||||
if localSetting == HistoryDefault {
|
if localSetting == HistoryDefault {
|
||||||
return HistoryPersistent
|
return HistoryPersistent
|
||||||
} else {
|
} else {
|
||||||
return localSetting
|
return localSetting
|
||||||
}
|
}
|
||||||
} else if serverSetting == PersistentOptIn {
|
case PersistentOptIn:
|
||||||
if localSetting >= HistoryEphemeral {
|
switch localSetting {
|
||||||
return localSetting
|
case HistoryPersistent:
|
||||||
} else {
|
return HistoryPersistent
|
||||||
|
case HistoryEphemeral, HistoryDefault:
|
||||||
|
return HistoryEphemeral
|
||||||
|
default:
|
||||||
return HistoryDisabled
|
return HistoryDisabled
|
||||||
}
|
}
|
||||||
} else {
|
case PersistentDisabled:
|
||||||
return HistoryDisabled
|
if localSetting == HistoryDisabled {
|
||||||
|
return HistoryDisabled
|
||||||
|
} else {
|
||||||
|
return HistoryEphemeral
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// PersistentUnspecified: shouldn't happen because the deserializer converts it
|
||||||
|
// to PersistentDisabled
|
||||||
|
if localSetting == HistoryDefault {
|
||||||
|
return HistoryEphemeral
|
||||||
|
} else {
|
||||||
|
return localSetting
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,8 +551,15 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
|
|||||||
if maxChathistoryLimit == 0 {
|
if maxChathistoryLimit == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
preposition := strings.ToLower(msg.Params[0])
|
||||||
|
target = msg.Params[1]
|
||||||
|
|
||||||
parseQueryParam := func(param string) (msgid string, timestamp time.Time, err error) {
|
parseQueryParam := func(param string) (msgid string, timestamp time.Time, err error) {
|
||||||
|
if param == "*" && (preposition == "before" || preposition == "between") {
|
||||||
|
// XXX compatibility with kiwi, which as of February 2020 is
|
||||||
|
// using BEFORE * as a synonym for LATEST *
|
||||||
|
return
|
||||||
|
}
|
||||||
err = utils.ErrInvalidParams
|
err = utils.ErrInvalidParams
|
||||||
pieces := strings.SplitN(param, "=", 2)
|
pieces := strings.SplitN(param, "=", 2)
|
||||||
if len(pieces) < 2 {
|
if len(pieces) < 2 {
|
||||||
@ -580,8 +587,6 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
preposition := strings.ToLower(msg.Params[0])
|
|
||||||
target = msg.Params[1]
|
|
||||||
channel, sequence, err = server.GetHistorySequence(nil, client, target)
|
channel, sequence, err = server.GetHistorySequence(nil, client, target)
|
||||||
if err != nil || sequence == nil {
|
if err != nil || sequence == nil {
|
||||||
return
|
return
|
||||||
@ -1995,17 +2000,19 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
|
|||||||
}
|
}
|
||||||
targetedItem := item
|
targetedItem := item
|
||||||
targetedItem.Params[0] = tnick
|
targetedItem.Params[0] = tnick
|
||||||
cPersistent, cEphemeral, _ := client.historyStatus(config)
|
cStatus, _ := client.historyStatus(config)
|
||||||
tPersistent, tEphemeral, _ := user.historyStatus(config)
|
tStatus, _ := user.historyStatus(config)
|
||||||
// add to ephemeral history
|
// add to ephemeral history
|
||||||
if cEphemeral {
|
if cStatus == HistoryEphemeral {
|
||||||
targetedItem.CfCorrespondent = tDetails.nickCasefolded
|
targetedItem.CfCorrespondent = tDetails.nickCasefolded
|
||||||
client.history.Add(targetedItem)
|
client.history.Add(targetedItem)
|
||||||
}
|
}
|
||||||
if tEphemeral && client != user {
|
if tStatus == HistoryEphemeral && client != user {
|
||||||
item.CfCorrespondent = details.nickCasefolded
|
item.CfCorrespondent = details.nickCasefolded
|
||||||
user.history.Add(item)
|
user.history.Add(item)
|
||||||
}
|
}
|
||||||
|
cPersistent := cStatus == HistoryPersistent
|
||||||
|
tPersistent := tStatus == HistoryPersistent
|
||||||
if cPersistent || tPersistent {
|
if cPersistent || tPersistent {
|
||||||
item.CfCorrespondent = ""
|
item.CfCorrespondent = ""
|
||||||
server.historyDB.AddDirectMessage(details.nickCasefolded, user.NickCasefolded(), cPersistent, tPersistent, targetedItem)
|
server.historyDB.AddDirectMessage(details.nickCasefolded, user.NickCasefolded(), cPersistent, tPersistent, targetedItem)
|
||||||
|
@ -864,46 +864,52 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
|||||||
// privilege checking.
|
// privilege checking.
|
||||||
func (server *Server) GetHistorySequence(providedChannel *Channel, client *Client, target string) (channel *Channel, sequence history.Sequence, err error) {
|
func (server *Server) GetHistorySequence(providedChannel *Channel, client *Client, target string) (channel *Channel, sequence history.Sequence, err error) {
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
|
// 4 cases: {persistent, ephemeral} x {normal, conversation}
|
||||||
|
// with ephemeral history, recipient is implicit in the choice of `hist`,
|
||||||
|
// and sender is "" if we're retrieving a channel or *, and the correspondent's name
|
||||||
|
// if we're retrieving a DM conversation ("query buffer"). with persistent history,
|
||||||
|
// recipient is always nonempty, and sender is either empty or nonempty as before.
|
||||||
|
var status HistoryStatus
|
||||||
var sender, recipient string
|
var sender, recipient string
|
||||||
var hist *history.Buffer
|
var hist *history.Buffer
|
||||||
if target == "*" {
|
channel = providedChannel
|
||||||
persistent, ephemeral, target := client.historyStatus(config)
|
if channel == nil {
|
||||||
if persistent {
|
if strings.HasPrefix(target, "#") {
|
||||||
recipient = target
|
channel = server.channels.Get(target)
|
||||||
} else if ephemeral {
|
if channel == nil {
|
||||||
hist = &client.history
|
return
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if channel != nil {
|
||||||
|
if !channel.hasClient(client) {
|
||||||
|
err = errInsufficientPrivs
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status, recipient = channel.historyStatus(config)
|
||||||
|
switch status {
|
||||||
|
case HistoryEphemeral:
|
||||||
|
hist = &channel.history
|
||||||
|
case HistoryPersistent:
|
||||||
|
// already set `recipient`
|
||||||
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
channel = providedChannel
|
status, recipient = client.historyStatus(config)
|
||||||
if channel == nil {
|
if target != "*" {
|
||||||
channel = server.channels.Get(target)
|
sender, err = CasefoldName(target)
|
||||||
}
|
|
||||||
if channel != nil {
|
|
||||||
if !channel.hasClient(client) {
|
|
||||||
err = errInsufficientPrivs
|
|
||||||
return
|
|
||||||
}
|
|
||||||
persistent, ephemeral, cfTarget := channel.historyStatus(config)
|
|
||||||
if persistent {
|
|
||||||
recipient = cfTarget
|
|
||||||
} else if ephemeral {
|
|
||||||
hist = &channel.history
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender = client.NickCasefolded()
|
|
||||||
var cfTarget string
|
|
||||||
cfTarget, err = CasefoldName(target)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
recipient = cfTarget
|
}
|
||||||
if !client.AlwaysOn() {
|
switch status {
|
||||||
hist = &client.history
|
case HistoryEphemeral:
|
||||||
}
|
hist = &client.history
|
||||||
|
case HistoryPersistent:
|
||||||
|
// already set `recipient`, and `sender` if necessary
|
||||||
|
default:
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,8 +927,9 @@ func (server *Server) GetHistorySequence(providedChannel *Channel, client *Clien
|
|||||||
if !cutoff.IsZero() {
|
if !cutoff.IsZero() {
|
||||||
cutoff = cutoff.Add(-time.Duration(config.History.Restrictions.GracePeriod))
|
cutoff = cutoff.Add(-time.Duration(config.History.Restrictions.GracePeriod))
|
||||||
}
|
}
|
||||||
|
|
||||||
if hist != nil {
|
if hist != nil {
|
||||||
sequence = hist.MakeSequence(recipient, cutoff)
|
sequence = hist.MakeSequence(sender, cutoff)
|
||||||
} else if recipient != "" {
|
} else if recipient != "" {
|
||||||
sequence = server.historyDB.MakeSequence(sender, recipient, cutoff)
|
sequence = server.historyDB.MakeSequence(sender, recipient, cutoff)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user