Remove verbose logging from cleanup and capture services

This commit is contained in:
Beingpax 2026-01-10 22:34:30 +05:45
parent 22b727ff97
commit d1fe77f2aa
4 changed files with 37 additions and 120 deletions

View File

@ -19,21 +19,18 @@ class CustomModelManager: ObservableObject {
func addCustomModel(_ model: CustomCloudModel) { func addCustomModel(_ model: CustomCloudModel) {
customModels.append(model) customModels.append(model)
saveCustomModels() saveCustomModels()
logger.info("Added custom model: \(model.displayName)")
} }
func removeCustomModel(withId id: UUID) { func removeCustomModel(withId id: UUID) {
customModels.removeAll { $0.id == id } customModels.removeAll { $0.id == id }
saveCustomModels() saveCustomModels()
APIKeyManager.shared.deleteCustomModelAPIKey(forModelId: id) APIKeyManager.shared.deleteCustomModelAPIKey(forModelId: id)
logger.info("Removed custom model with ID: \(id)")
} }
func updateCustomModel(_ updatedModel: CustomCloudModel) { func updateCustomModel(_ updatedModel: CustomCloudModel) {
if let index = customModels.firstIndex(where: { $0.id == updatedModel.id }) { if let index = customModels.firstIndex(where: { $0.id == updatedModel.id }) {
customModels[index] = updatedModel customModels[index] = updatedModel
saveCustomModels() saveCustomModels()
logger.info("Updated custom model: \(updatedModel.displayName)")
} }
} }
@ -41,7 +38,6 @@ class CustomModelManager: ObservableObject {
private func loadCustomModels() { private func loadCustomModels() {
guard let data = userDefaults.data(forKey: customModelsKey) else { guard let data = userDefaults.data(forKey: customModelsKey) else {
logger.info("No custom models found in UserDefaults")
return return
} }

View File

@ -1,7 +1,6 @@
import Foundation import Foundation
import AppKit import AppKit
import Vision import Vision
import os
import ScreenCaptureKit import ScreenCaptureKit
@MainActor @MainActor
@ -9,11 +8,6 @@ class ScreenCaptureService: ObservableObject {
@Published var isCapturing = false @Published var isCapturing = false
@Published var lastCapturedText: String? @Published var lastCapturedText: String?
private let logger = Logger(
subsystem: "com.prakashjoshipax.voiceink",
category: "aienhancement"
)
private struct WindowCandidate { private struct WindowCandidate {
let title: String let title: String
let ownerName: String let ownerName: String
@ -88,7 +82,6 @@ class ScreenCaptureService: ObservableObject {
return NSImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height)) return NSImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height))
} catch { } catch {
logger.notice("📸 Screen capture failed: \(error.localizedDescription, privacy: .public)")
return nil return nil
} }
} }
@ -125,8 +118,7 @@ class ScreenCaptureService: ObservableObject {
switch result { switch result {
case .success(let text): case .success(let text):
return text return text
case .failure(let error): case .failure:
logger.notice("📸 Text recognition failed: \(error.localizedDescription, privacy: .public)")
return nil return nil
} }
} }
@ -144,12 +136,9 @@ class ScreenCaptureService: ObservableObject {
} }
guard let windowInfo = getActiveWindowInfo() else { guard let windowInfo = getActiveWindowInfo() else {
logger.notice("📸 No active window found")
return nil return nil
} }
logger.notice("📸 Capturing: \(windowInfo.title, privacy: .public) (\(windowInfo.ownerName, privacy: .public))")
var contextText = """ var contextText = """
Active Window: \(windowInfo.title) Active Window: \(windowInfo.title)
Application: \(windowInfo.ownerName) Application: \(windowInfo.ownerName)
@ -161,11 +150,8 @@ class ScreenCaptureService: ObservableObject {
if let extractedText = extractedText, !extractedText.isEmpty { if let extractedText = extractedText, !extractedText.isEmpty {
contextText += "Window Content:\n\(extractedText)" contextText += "Window Content:\n\(extractedText)"
let preview = String(extractedText.prefix(100))
logger.notice("📸 Text extracted: \(preview, privacy: .public)\(extractedText.count > 100 ? "..." : "")")
} else { } else {
contextText += "Window Content:\nNo text detected via OCR" contextText += "Window Content:\nNo text detected via OCR"
logger.notice("📸 No text extracted from window")
} }
await MainActor.run { await MainActor.run {
@ -175,7 +161,6 @@ class ScreenCaptureService: ObservableObject {
return contextText return contextText
} }
logger.notice("📸 Window capture failed")
return nil return nil
} }
} }

View File

@ -1,26 +1,20 @@
import Foundation import Foundation
import SwiftData import SwiftData
import OSLog
/// A utility class that manages automatic cleanup of audio files while preserving transcript data /// A utility class that manages automatic cleanup of audio files while preserving transcript data
class AudioCleanupManager { class AudioCleanupManager {
static let shared = AudioCleanupManager() static let shared = AudioCleanupManager()
private let logger = Logger(subsystem: "com.prakashjoshipax.voiceink", category: "AudioCleanupManager")
private var cleanupTimer: Timer? private var cleanupTimer: Timer?
// Default cleanup settings // Default cleanup settings
private let defaultRetentionDays = 7 private let defaultRetentionDays = 7
private let cleanupCheckInterval: TimeInterval = 86400 // Check once per day (in seconds) private let cleanupCheckInterval: TimeInterval = 86400 // Check once per day (in seconds)
private init() { private init() {}
logger.info("AudioCleanupManager initialized")
}
/// Start the automatic cleanup process /// Start the automatic cleanup process
func startAutomaticCleanup(modelContext: ModelContext) { func startAutomaticCleanup(modelContext: ModelContext) {
logger.info("Starting automatic audio cleanup")
// Cancel any existing timer // Cancel any existing timer
cleanupTimer?.invalidate() cleanupTimer?.invalidate()
@ -35,21 +29,16 @@ class AudioCleanupManager {
await self?.performCleanup(modelContext: modelContext) await self?.performCleanup(modelContext: modelContext)
} }
} }
logger.info("Automatic cleanup scheduled")
} }
/// Stop the automatic cleanup process /// Stop the automatic cleanup process
func stopAutomaticCleanup() { func stopAutomaticCleanup() {
logger.info("Stopping automatic audio cleanup")
cleanupTimer?.invalidate() cleanupTimer?.invalidate()
cleanupTimer = nil cleanupTimer = nil
} }
/// Get information about the files that would be cleaned up /// Get information about the files that would be cleaned up
func getCleanupInfo(modelContext: ModelContext) async -> (fileCount: Int, totalSize: Int64, transcriptions: [Transcription]) { func getCleanupInfo(modelContext: ModelContext) async -> (fileCount: Int, totalSize: Int64, transcriptions: [Transcription]) {
logger.info("Analyzing potential audio cleanup")
// Get retention period from UserDefaults // Get retention period from UserDefaults
let retentionDays = UserDefaults.standard.integer(forKey: "AudioRetentionPeriod") let retentionDays = UserDefaults.standard.integer(forKey: "AudioRetentionPeriod")
let effectiveRetentionDays = retentionDays > 0 ? retentionDays : defaultRetentionDays let effectiveRetentionDays = retentionDays > 0 ? retentionDays : defaultRetentionDays
@ -57,7 +46,6 @@ class AudioCleanupManager {
// Calculate the cutoff date // Calculate the cutoff date
let calendar = Calendar.current let calendar = Calendar.current
guard let cutoffDate = calendar.date(byAdding: .day, value: -effectiveRetentionDays, to: Date()) else { guard let cutoffDate = calendar.date(byAdding: .day, value: -effectiveRetentionDays, to: Date()) else {
logger.error("Failed to calculate cutoff date")
return (0, 0, []) return (0, 0, [])
} }
@ -83,55 +71,38 @@ class AudioCleanupManager {
if let urlString = transcription.audioFileURL, if let urlString = transcription.audioFileURL,
let url = URL(string: urlString), let url = URL(string: urlString),
FileManager.default.fileExists(atPath: url.path) { FileManager.default.fileExists(atPath: url.path) {
do { if let attributes = try? FileManager.default.attributesOfItem(atPath: url.path),
// Get file attributes to determine size let fileSize = attributes[.size] as? Int64 {
let attributes = try FileManager.default.attributesOfItem(atPath: url.path) totalSize += fileSize
if let fileSize = attributes[.size] as? Int64 { fileCount += 1
totalSize += fileSize eligibleTranscriptions.append(transcription)
fileCount += 1
eligibleTranscriptions.append(transcription)
}
} catch {
self.logger.error("Failed to get attributes for \(url.lastPathComponent): \(error.localizedDescription)")
} }
} }
} }
self.logger.info("Found \(fileCount) files eligible for cleanup, totaling \(self.formatFileSize(totalSize))")
return (fileCount, totalSize, eligibleTranscriptions) return (fileCount, totalSize, eligibleTranscriptions)
} }
} catch { } catch {
logger.error("Error analyzing files for cleanup: \(error.localizedDescription)")
return (0, 0, []) return (0, 0, [])
} }
} }
/// Perform the cleanup operation /// Perform the cleanup operation
private func performCleanup(modelContext: ModelContext) async { private func performCleanup(modelContext: ModelContext) async {
logger.info("Performing audio cleanup")
// Get retention period from UserDefaults // Get retention period from UserDefaults
let retentionDays = UserDefaults.standard.integer(forKey: "AudioRetentionPeriod") let retentionDays = UserDefaults.standard.integer(forKey: "AudioRetentionPeriod")
let effectiveRetentionDays = retentionDays > 0 ? retentionDays : defaultRetentionDays let effectiveRetentionDays = retentionDays > 0 ? retentionDays : defaultRetentionDays
// Check if automatic cleanup is enabled // Check if automatic cleanup is enabled
let isCleanupEnabled = UserDefaults.standard.bool(forKey: "IsAudioCleanupEnabled") let isCleanupEnabled = UserDefaults.standard.bool(forKey: "IsAudioCleanupEnabled")
guard isCleanupEnabled else { guard isCleanupEnabled else { return }
logger.info("Audio cleanup is disabled, skipping")
return
}
logger.info("Audio retention period: \(effectiveRetentionDays) days")
// Calculate the cutoff date // Calculate the cutoff date
let calendar = Calendar.current let calendar = Calendar.current
guard let cutoffDate = calendar.date(byAdding: .day, value: -effectiveRetentionDays, to: Date()) else { guard let cutoffDate = calendar.date(byAdding: .day, value: -effectiveRetentionDays, to: Date()) else {
logger.error("Failed to calculate cutoff date")
return return
} }
logger.info("Cutoff date for audio cleanup: \(cutoffDate)")
do { do {
// Execute SwiftData operations on the main thread // Execute SwiftData operations on the main thread
try await MainActor.run { try await MainActor.run {
@ -144,38 +115,24 @@ class AudioCleanupManager {
) )
let transcriptions = try modelContext.fetch(descriptor) let transcriptions = try modelContext.fetch(descriptor)
self.logger.info("Found \(transcriptions.count) transcriptions with audio files to clean up")
var deletedCount = 0 var deletedCount = 0
var errorCount = 0
for transcription in transcriptions { for transcription in transcriptions {
if let urlString = transcription.audioFileURL, if let urlString = transcription.audioFileURL,
let url = URL(string: urlString), let url = URL(string: urlString),
FileManager.default.fileExists(atPath: url.path) { FileManager.default.fileExists(atPath: url.path) {
do { try? FileManager.default.removeItem(at: url)
// Delete the audio file transcription.audioFileURL = nil
try FileManager.default.removeItem(at: url) deletedCount += 1
// Update the transcription to remove the audio file reference
transcription.audioFileURL = nil
deletedCount += 1
self.logger.debug("Deleted audio file: \(url.lastPathComponent)")
} catch {
errorCount += 1
self.logger.error("Failed to delete audio file \(url.lastPathComponent): \(error.localizedDescription)")
}
} }
} }
if deletedCount > 0 || errorCount > 0 { if deletedCount > 0 {
try modelContext.save() try modelContext.save()
self.logger.info("Cleanup complete. Deleted \(deletedCount) files. Failed: \(errorCount)")
} }
} }
} catch { } catch {
logger.error("Error during audio cleanup: \(error.localizedDescription)") // Silently fail - cleanup is non-critical
} }
} }
@ -186,8 +143,6 @@ class AudioCleanupManager {
/// Run cleanup on the specified transcriptions /// Run cleanup on the specified transcriptions
func runCleanupForTranscriptions(modelContext: ModelContext, transcriptions: [Transcription]) async -> (deletedCount: Int, errorCount: Int) { func runCleanupForTranscriptions(modelContext: ModelContext, transcriptions: [Transcription]) async -> (deletedCount: Int, errorCount: Int) {
logger.info("Running cleanup for \(transcriptions.count) specific transcriptions")
do { do {
// Execute SwiftData operations on the main thread // Execute SwiftData operations on the main thread
return try await MainActor.run { return try await MainActor.run {
@ -199,34 +154,22 @@ class AudioCleanupManager {
let url = URL(string: urlString), let url = URL(string: urlString),
FileManager.default.fileExists(atPath: url.path) { FileManager.default.fileExists(atPath: url.path) {
do { do {
// Delete the audio file
try FileManager.default.removeItem(at: url) try FileManager.default.removeItem(at: url)
// Update the transcription to remove the audio file reference
transcription.audioFileURL = nil transcription.audioFileURL = nil
deletedCount += 1 deletedCount += 1
self.logger.debug("Deleted audio file: \(url.lastPathComponent)")
} catch { } catch {
errorCount += 1 errorCount += 1
self.logger.error("Failed to delete audio file \(url.lastPathComponent): \(error.localizedDescription)")
} }
} }
} }
if deletedCount > 0 || errorCount > 0 { if deletedCount > 0 || errorCount > 0 {
do { try? modelContext.save()
try modelContext.save()
self.logger.info("Cleanup complete. Deleted \(deletedCount) files. Failed: \(errorCount)")
} catch {
self.logger.error("Error saving model context after cleanup: \(error.localizedDescription)")
}
} }
return (deletedCount, errorCount) return (deletedCount, errorCount)
} }
} catch { } catch {
logger.error("Error during targeted cleanup: \(error.localizedDescription)")
return (0, 0) return (0, 0)
} }
} }

View File

@ -49,13 +49,6 @@ struct VoiceInkApp: App {
// Attempt 1: Try persistent storage // Attempt 1: Try persistent storage
if let persistentContainer = Self.createPersistentContainer(schema: schema, logger: logger) { if let persistentContainer = Self.createPersistentContainer(schema: schema, logger: logger) {
container = persistentContainer container = persistentContainer
#if DEBUG
// Print SwiftData storage location in debug builds only
if let url = persistentContainer.mainContext.container.configurations.first?.url {
print("💾 SwiftData storage location: \(url.path)")
}
#endif
} }
// Attempt 2: Try in-memory storage // Attempt 2: Try in-memory storage
else if let memoryContainer = Self.createInMemoryContainer(schema: schema, logger: logger) { else if let memoryContainer = Self.createInMemoryContainer(schema: schema, logger: logger) {