88 lines
3.2 KiB
Swift
88 lines
3.2 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import SignalServiceKit
|
|
import SignalUI
|
|
|
|
#if USE_DEBUG_UI
|
|
|
|
class DebugUIDiskUsage: DebugUIPage, Dependencies {
|
|
|
|
let name = "Orphans & Disk Usage"
|
|
|
|
func section(thread: TSThread?) -> OWSTableSection? {
|
|
return OWSTableSection(title: name, items: [
|
|
OWSTableItem(title: "Audit & Log",
|
|
actionBlock: { OWSOrphanDataCleaner.auditAndCleanup(false) }),
|
|
OWSTableItem(title: "Audit & Clean Up",
|
|
actionBlock: { OWSOrphanDataCleaner.auditAndCleanup(true) }),
|
|
OWSTableItem(title: "Clear All Attachment Thumbnails",
|
|
actionBlock: { DebugUIDiskUsage.clearAllAttachmentThumbnails() }),
|
|
OWSTableItem(title: "Delete Messages older than 3 Months",
|
|
actionBlock: { DebugUIDiskUsage.deleteOldMessages_3Months() })
|
|
])
|
|
}
|
|
|
|
private static func clearAllAttachmentThumbnails() {
|
|
let fileManager = FileManager.default
|
|
guard let cacheContents = fileManager.enumerator(
|
|
at: URL(fileURLWithPath: OWSFileSystem.cachesDirectoryPath()),
|
|
includingPropertiesForKeys: nil,
|
|
options: [ .skipsSubdirectoryDescendants ],
|
|
errorHandler: { url, error in
|
|
Logger.warn("could not visit \(url): \(error)")
|
|
return true
|
|
}
|
|
) else {
|
|
Logger.error("Failed to enumerate caches.")
|
|
return
|
|
}
|
|
|
|
var removedCount: UInt = 0
|
|
for case let cacheItem as URL in cacheContents {
|
|
let itemName = cacheItem.lastPathComponent
|
|
guard itemName.hasSuffix("-thumbnails") || itemName.hasSuffix("-signal-ios-thumbnail.jpg") else { continue }
|
|
|
|
do {
|
|
try fileManager.removeItem(at: cacheItem)
|
|
removedCount += 1
|
|
} catch {
|
|
Logger.warn("Could not remove \(cacheItem): \(error)")
|
|
}
|
|
}
|
|
Logger.info("Deleted \(removedCount) items.")
|
|
}
|
|
|
|
private static func deleteOldMessages_3Months() {
|
|
deleteOldMessages(maxAgeSeconds: kMonthInterval * 3)
|
|
}
|
|
|
|
private static func deleteOldMessages(maxAgeSeconds: TimeInterval) {
|
|
databaseStorage.write { transaction in
|
|
let threadIds = TSThread.anyAllUniqueIds(transaction: transaction)
|
|
var interactionsToDelete: [TSInteraction] = []
|
|
for threadId in threadIds {
|
|
let interactionFinder = InteractionFinder(threadUniqueId: threadId)
|
|
do {
|
|
try interactionFinder.enumerateRecentInteractions(transaction: transaction) { interaction, stop in
|
|
let ageSeconds = abs(interaction.receivedAtDate.timeIntervalSinceNow)
|
|
if ageSeconds >= maxAgeSeconds {
|
|
interactionsToDelete.append(interaction)
|
|
}
|
|
}
|
|
} catch { }
|
|
}
|
|
|
|
Logger.info("Deleting \(interactionsToDelete.count) interactions.")
|
|
|
|
for interation in interactionsToDelete {
|
|
interation.anyRemove(transaction: transaction)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|