diff options
Diffstat (limited to 'DomainDig')
| -rw-r--r-- | DomainDig/ContentView.swift | 42 | ||||
| -rw-r--r-- | DomainDig/DomainViewModel.swift | 70 | ||||
| -rw-r--r-- | DomainDig/WatchlistView.swift | 11 | ||||
| -rw-r--r-- | DomainDig/WorkflowsView.swift | 22 |
4 files changed, 46 insertions, 99 deletions
diff --git a/DomainDig/ContentView.swift b/DomainDig/ContentView.swift index 30d693e..b5ec729 100644 --- a/DomainDig/ContentView.swift +++ b/DomainDig/ContentView.swift @@ -710,50 +710,20 @@ struct ContentView: View { } private func shareSingleResults(format: DomainExportFormat) { - let (filename, data) = exportPayload( - prefix: "domaindig_single", - format: format, - text: viewModel.exportText(), - csv: viewModel.exportCSV(), - json: viewModel.exportJSONData() - ) - ExportPresenter.share(filename: filename, data: data) + guard let data = viewModel.exportSingleReportData(format: format) else { return } + ExportPresenter.share(filename: exportFilename(prefix: "domaindig_single", format: format), data: data) } private func shareBatchResults(format: DomainExportFormat) { - let (filename, data) = exportPayload( - prefix: "domaindig_batch", - format: format, - text: viewModel.exportBatchText(), - csv: viewModel.exportBatchCSV(), - json: viewModel.exportBatchJSONData() - ) - ExportPresenter.share(filename: filename, data: data) + guard let data = viewModel.exportBatchReportData(format: format) else { return } + ExportPresenter.share(filename: exportFilename(prefix: "domaindig_batch", format: format), data: data) } - private func exportPayload( - prefix: String, - format: DomainExportFormat, - text: String, - csv: String, - json: Data? - ) -> (String, Data) { + private func exportFilename(prefix: String, format: DomainExportFormat) -> String { let formatter = DateFormatter() formatter.dateFormat = "yyyyMMdd_HHmmss" let timestamp = formatter.string(from: Date()) - let filename = "\(timestamp)_\(prefix).\(format.fileExtension)" - let data: Data - - switch format { - case .text: - data = Data(text.utf8) - case .csv: - data = Data(csv.utf8) - case .json: - data = json ?? Data("[]".utf8) - } - - return (filename, data) + return "\(timestamp)_\(prefix).\(format.fileExtension)" } private var defaultCollapsedSections: Set<ResultSection> { diff --git a/DomainDig/DomainViewModel.swift b/DomainDig/DomainViewModel.swift index 33756df..674efdf 100644 --- a/DomainDig/DomainViewModel.swift +++ b/DomainDig/DomainViewModel.swift @@ -1521,16 +1521,6 @@ final class DomainViewModel { } } - func exportText() -> String { - guard let currentReport else { return "No results available." } - return DomainReportExporter.text(for: currentReport) - } - - func exportCSV() -> String { - guard let currentReport else { return DomainReportExporter.csv(for: []) } - return DomainReportExporter.csv(for: [currentReport]) - } - func exportJSONData() -> Data? { guard let currentReport else { return nil } return try? DomainReportExporter.data(for: currentReport, format: .json) @@ -1541,6 +1531,11 @@ final class DomainViewModel { return String(data: data, encoding: .utf8) } + func exportSingleReportData(format: DomainExportFormat) -> Data? { + guard let currentReport else { return nil } + return try? DomainReportExporter.data(for: currentReport, format: format) + } + func audits(for domain: String) -> [AuditSession] { auditSessions .filter { $0.domain.caseInsensitiveCompare(domain) == .orderedSame } @@ -1792,40 +1787,18 @@ final class DomainViewModel { usageCredits = Dictionary(uniqueKeysWithValues: statuses.map { ($0.feature, $0) }) } - func exportBatchText() -> String { - DomainReportExporter.batchText( - for: currentBatchReports(), - title: batchLookupSource == .watchlistRefresh ? "Tracked Domains Export" : "Batch Results Export" - ) - } - - func exportBatchCSV() -> String { - DomainReportExporter.csv(for: currentBatchReports()) - } - - func exportBatchJSONData() -> Data? { + func exportBatchReportData(format: DomainExportFormat) -> Data? { try? DomainReportExporter.data( for: currentBatchReports(), - format: .json, + format: format, title: batchLookupSource == .watchlistRefresh ? "Tracked Domains Export" : "Batch Results Export" ) } - func exportTrackedDomainsCSV(domains: [TrackedDomain]) -> String { - DomainReportExporter.csv(for: reports(for: domains)) - } - - func exportTrackedDomainsText(domains: [TrackedDomain]) -> String { - DomainReportExporter.batchText( - for: reports(for: domains), - title: "Tracked Domains Export" - ) - } - - func exportTrackedDomainsJSONData(domains: [TrackedDomain]) -> Data? { + func exportTrackedDomainsData(domains: [TrackedDomain], format: DomainExportFormat) -> Data? { try? DomainReportExporter.data( for: reports(for: domains), - format: .json, + format: format, title: "Tracked Domains Export" ) } @@ -1934,6 +1907,31 @@ final class DomainViewModel { return try? encoder.encode(payload) } + func exportWorkflowMarkdown(summary: WorkflowRunSummary, changedOnly: Bool) -> String { + let reports = workflowReports(from: summary, changedOnly: changedOnly) + let base = DomainReportExporter.batchMarkdown(for: reports, title: "\(summary.workflowName) Workflow Export") + guard !summary.workflowInsights.isEmpty else { return base } + let insightLines = summary.workflowInsights.map { + "- \($0.description): \($0.domainsInvolved.joined(separator: ", "))" + } + return (["## \(summary.workflowName) Workflow Insights"] + insightLines + ["", base]).joined(separator: "\n") + } + + func exportWorkflowData(summary: WorkflowRunSummary, changedOnly: Bool, format: DomainExportFormat) -> Data? { + switch format { + case .text: + return Data(exportWorkflowText(summary: summary, changedOnly: changedOnly).utf8) + case .csv: + return Data(exportWorkflowCSV(summary: summary, changedOnly: changedOnly).utf8) + case .json: + return exportWorkflowJSONData(summary: summary, changedOnly: changedOnly) + case .markdown: + return Data(exportWorkflowMarkdown(summary: summary, changedOnly: changedOnly).utf8) + case .pdf: + return DomainReportExporter.pdfData(fromMarkdown: exportWorkflowMarkdown(summary: summary, changedOnly: changedOnly)) + } + } + private func performLookup(domain: String, lookupID: UUID) async -> HistoryEntry? { let lookupStartedAt = DomainDebugLog.signpostStart("DomainViewModel.performLookup", domain: domain) let previous = previousSnapshot( diff --git a/DomainDig/WatchlistView.swift b/DomainDig/WatchlistView.swift index e017502..a1af244 100644 --- a/DomainDig/WatchlistView.swift +++ b/DomainDig/WatchlistView.swift @@ -388,15 +388,8 @@ struct WatchlistView: View { formatter.dateFormat = "yyyyMMdd_HHmmss" let timestamp = formatter.string(from: Date()) let filename = "\(timestamp)_domaindig_watchlist.\(format.fileExtension)" - let data: Data - - switch format { - case .text: - data = Data(viewModel.exportTrackedDomainsText(domains: viewModel.filteredTrackedDomains).utf8) - case .csv: - data = Data(viewModel.exportTrackedDomainsCSV(domains: viewModel.filteredTrackedDomains).utf8) - case .json: - data = viewModel.exportTrackedDomainsJSONData(domains: viewModel.filteredTrackedDomains) ?? Data("[]".utf8) + guard let data = viewModel.exportTrackedDomainsData(domains: viewModel.filteredTrackedDomains, format: format) else { + return } ExportPresenter.share(filename: filename, data: data) diff --git a/DomainDig/WorkflowsView.swift b/DomainDig/WorkflowsView.swift index 11273c7..e1cea09 100644 --- a/DomainDig/WorkflowsView.swift +++ b/DomainDig/WorkflowsView.swift @@ -383,15 +383,8 @@ struct WorkflowDetailView: View { formatter.dateFormat = "yyyyMMdd_HHmmss" let timestamp = formatter.string(from: Date()) let filename = "\(timestamp)_workflow_\(latestSummary.workflowName.replacingOccurrences(of: " ", with: "_").lowercased()).\(format.fileExtension)" - let data: Data - - switch format { - case .text: - data = Data(viewModel.exportWorkflowText(summary: latestSummary, changedOnly: changedOnly).utf8) - case .csv: - data = Data(viewModel.exportWorkflowCSV(summary: latestSummary, changedOnly: changedOnly).utf8) - case .json: - data = viewModel.exportWorkflowJSONData(summary: latestSummary, changedOnly: changedOnly) ?? Data("[]".utf8) + guard let data = viewModel.exportWorkflowData(summary: latestSummary, changedOnly: changedOnly, format: format) else { + return } ExportPresenter.share(filename: filename, data: data) @@ -586,15 +579,8 @@ struct WorkflowRunSummaryView: View { formatter.dateFormat = "yyyyMMdd_HHmmss" let timestamp = formatter.string(from: Date()) let filename = "\(timestamp)_workflow_summary.\(format.fileExtension)" - let data: Data - - switch format { - case .text: - data = Data(viewModel.exportWorkflowText(summary: summary, changedOnly: changedOnly).utf8) - case .csv: - data = Data(viewModel.exportWorkflowCSV(summary: summary, changedOnly: changedOnly).utf8) - case .json: - data = viewModel.exportWorkflowJSONData(summary: summary, changedOnly: changedOnly) ?? Data("[]".utf8) + guard let data = viewModel.exportWorkflowData(summary: summary, changedOnly: changedOnly, format: format) else { + return } ExportPresenter.share(filename: filename, data: data) |
