mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 11:19:36 +01:00
[Chore]: Patch getLargestUid function
Now preventing uid-drift. Also fixing the monstrocity that was statistics-store formatting
This commit is contained in:
parent
d8b19dcd26
commit
dc79d52245
2 changed files with 29 additions and 50 deletions
|
|
@ -31,6 +31,22 @@ class MailProcessingService extends EventEmitter {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this._deleteOldMails()
|
this._deleteOldMails()
|
||||||
}, this.config.imap.refreshIntervalSeconds * 1000)
|
}, this.config.imap.refreshIntervalSeconds * 1000)
|
||||||
|
|
||||||
|
// Periodically ground largestUid to IMAP state every 5 minutes
|
||||||
|
setInterval(async() => {
|
||||||
|
try {
|
||||||
|
if (this.statisticsStore && this.imapService) {
|
||||||
|
const realLargestUid = await this.imapService.getLargestUid();
|
||||||
|
if (realLargestUid && realLargestUid !== this.statisticsStore.largestUid) {
|
||||||
|
this.statisticsStore.largestUid = realLargestUid;
|
||||||
|
this.statisticsStore._saveToDatabase && this.statisticsStore._saveToDatabase();
|
||||||
|
debug(`Grounded statisticsStore.largestUid to IMAP: ${realLargestUid}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
debug('Error grounding largestUid to IMAP:', err.message);
|
||||||
|
}
|
||||||
|
}, 60 * 1000); // 1 minute
|
||||||
}
|
}
|
||||||
|
|
||||||
_initCache() {
|
_initCache() {
|
||||||
|
|
|
||||||
|
|
@ -405,9 +405,7 @@ class StatisticsStore {
|
||||||
recordDelete() {
|
recordDelete() {
|
||||||
this.currentCount = Math.max(0, this.currentCount - 1)
|
this.currentCount = Math.max(0, this.currentCount - 1)
|
||||||
this._addDataPoint('delete')
|
this._addDataPoint('delete')
|
||||||
debug(`
|
debug(`Email deleted. Current: ${this.currentCount}`)
|
||||||
Email deleted.Current: $ { this.currentCount }
|
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -415,8 +413,7 @@ class StatisticsStore {
|
||||||
*/
|
*/
|
||||||
recordForward() {
|
recordForward() {
|
||||||
this._addDataPoint('forward')
|
this._addDataPoint('forward')
|
||||||
debug(`
|
debug(`Email forwarded. Current: ${this.currentCount}`)
|
||||||
Email forwarded `)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -470,18 +467,12 @@ class StatisticsStore {
|
||||||
|
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
if (this.enhancedStats && (now - this.lastEnhancedStatsTime) < this.enhancedStatsCacheDuration) {
|
if (this.enhancedStats && (now - this.lastEnhancedStatsTime) < this.enhancedStatsCacheDuration) {
|
||||||
debug(`
|
debug(`Using cached enhanced stats(age: ${Math.round((now - this.lastEnhancedStatsTime) / 1000)}s)`)
|
||||||
Using cached enhanced stats(age: $ { Math.round((now - this.lastEnhancedStatsTime) / 1000) }
|
|
||||||
s)
|
|
||||||
`)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(`
|
debug(`Calculating enhanced statistics from ${allMails.length} emails `)
|
||||||
Calculating enhanced statistics from $ { allMails.length }
|
// Track sender domains (privacy-friendly: domain only, not full address)
|
||||||
emails `)
|
|
||||||
|
|
||||||
// Track sender domains (privacy-friendly: domain only, not full address)
|
|
||||||
const senderDomains = new Map()
|
const senderDomains = new Map()
|
||||||
const recipientDomains = new Map()
|
const recipientDomains = new Map()
|
||||||
const hourlyActivity = Array(24).fill(0)
|
const hourlyActivity = Array(24).fill(0)
|
||||||
|
|
@ -591,10 +582,7 @@ class StatisticsStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastEnhancedStatsTime = now
|
this.lastEnhancedStatsTime = now
|
||||||
debug(`
|
debug(`Enhanced stats calculated: ${this.enhancedStats.uniqueSenderDomains} unique sender domains, ${this.enhancedStats.busiestHours.length} busy hours `)
|
||||||
Enhanced stats calculated: $ { this.enhancedStats.uniqueSenderDomains }
|
|
||||||
unique sender domains, $ { this.enhancedStats.busiestHours.length }
|
|
||||||
busy hours `)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -610,18 +598,11 @@ class StatisticsStore {
|
||||||
// Check cache - if analysis was done recently, skip it
|
// Check cache - if analysis was done recently, skip it
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
if (this.historicalData && (now - this.lastAnalysisTime) < this.analysisCacheDuration) {
|
if (this.historicalData && (now - this.lastAnalysisTime) < this.analysisCacheDuration) {
|
||||||
debug(`
|
debug(`Using cached historical data(${this.historicalData.length} points, age: ${Math.round((now - this.lastAnalysisTime) / 1000)}s)`)
|
||||||
Using cached historical data($ { this.historicalData.length }
|
|
||||||
points, age: $ { Math.round((now - this.lastAnalysisTime) / 1000) }
|
|
||||||
s)
|
|
||||||
`)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(`
|
debug(`Analyzing ${allMails.length} emails for historical statistics `)
|
||||||
Analyzing $ { allMails.length }
|
|
||||||
emails
|
|
||||||
for historical statistics `)
|
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
|
|
||||||
// Group emails by minute
|
// Group emails by minute
|
||||||
|
|
@ -651,10 +632,7 @@ class StatisticsStore {
|
||||||
this.lastAnalysisTime = now
|
this.lastAnalysisTime = now
|
||||||
|
|
||||||
const elapsed = Date.now() - startTime
|
const elapsed = Date.now() - startTime
|
||||||
debug(`
|
debug(`Built historical data: ${this.historicalData.length} time buckets in ${elapsed} ms `)
|
||||||
Built historical data: $ { this.historicalData.length }
|
|
||||||
time buckets in $ { elapsed }
|
|
||||||
ms `)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -742,11 +720,7 @@ class StatisticsStore {
|
||||||
.map(([timestamp, receives]) => ({ timestamp, receives }))
|
.map(([timestamp, receives]) => ({ timestamp, receives }))
|
||||||
.sort((a, b) => a.timestamp - b.timestamp)
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
|
|
||||||
debug(`
|
debug(`Historical timeline: ${intervalData.length} 15 - min interval points within ${config.email.purgeTime.time} ${config.email.purgeTime.unit} window `)
|
||||||
Historical timeline: $ { intervalData.length }
|
|
||||||
15 - min interval points within $ { config.email.purgeTime.time }
|
|
||||||
$ { config.email.purgeTime.unit }
|
|
||||||
window `)
|
|
||||||
return intervalData
|
return intervalData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -786,11 +760,7 @@ class StatisticsStore {
|
||||||
hourlyAverages.set(hour, avg)
|
hourlyAverages.set(hour, avg)
|
||||||
})
|
})
|
||||||
|
|
||||||
debug(`
|
debug(`Built hourly patterns for ${hourlyAverages.size} hours from ${this.historicalData.length} data points `)
|
||||||
Built hourly patterns
|
|
||||||
for $ { hourlyAverages.size }
|
|
||||||
hours from $ { this.historicalData.length }
|
|
||||||
data points `)
|
|
||||||
|
|
||||||
// Generate predictions for a reasonable future window
|
// Generate predictions for a reasonable future window
|
||||||
// Limit to 20% of purge duration or 12 hours max to maintain chart balance
|
// Limit to 20% of purge duration or 12 hours max to maintain chart balance
|
||||||
|
|
@ -826,9 +796,7 @@ class StatisticsStore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(`
|
debug(`Generated ${predictions.length} prediction points based on hourly patterns `)
|
||||||
Generated $ { predictions.length }
|
|
||||||
prediction points based on hourly patterns `)
|
|
||||||
return predictions
|
return predictions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -881,12 +849,7 @@ class StatisticsStore {
|
||||||
|
|
||||||
if (beforeCount !== this.hourlyData.length) {
|
if (beforeCount !== this.hourlyData.length) {
|
||||||
this._saveToDatabase() // Save after cleanup
|
this._saveToDatabase() // Save after cleanup
|
||||||
debug(`
|
debug(`Cleaned up ${beforeCount - this.hourlyData.length} old data points(keeping data for ${config.email.purgeTime.time} ${config.email.purgeTime.unit})`)
|
||||||
Cleaned up $ { beforeCount - this.hourlyData.length }
|
|
||||||
old data points(keeping data
|
|
||||||
for $ { config.email.purgeTime.time }
|
|
||||||
$ { config.email.purgeTime.unit })
|
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastCleanup = now
|
this.lastCleanup = now
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue