Add local source ingest and podcasts

This commit is contained in:
Krishna Kumar
2026-07-02 01:11:03 -05:00
parent 4d875e12d6
commit f8693f4be0
18 changed files with 1044 additions and 31 deletions

View File

@@ -0,0 +1,95 @@
import Foundation
struct IngestPayload: Equatable, Sendable {
let url: String
let title: String?
let notes: String
}
enum IngestPayloadParser {
static func parse(item: Any?, typeIdentifier: String? = nil) -> IngestPayload? {
if let url = item as? URL {
return payload(from: url.absoluteString, notes: "")
}
if let attributed = item as? NSAttributedString {
return payload(from: attributed.string, notes: attributed.string)
}
if let string = item as? String {
return payload(from: string, notes: shouldKeepNotes(for: typeIdentifier) ? string : "")
}
if let data = item as? Data,
let string = String(data: data, encoding: .utf8) ?? String(data: data, encoding: .ascii) {
return payload(from: string, notes: shouldKeepNotes(for: typeIdentifier) ? string : "")
}
return nil
}
private static func payload(from text: String, notes: String) -> IngestPayload? {
guard let url = firstWebURL(in: text) else { return nil }
return IngestPayload(url: url, title: nil, notes: cleanedNotes(notes, excluding: url))
}
static func firstWebURL(in text: String) -> String? {
if let direct = URL(string: text.trimmingCharacters(in: .whitespacesAndNewlines)),
isBookmarkable(direct) {
return direct.absoluteString
}
let decoded = decodeHTML(text)
let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let range = NSRange(decoded.startIndex..<decoded.endIndex, in: decoded)
let match = detector?.matches(in: decoded, range: range).first { result in
guard let url = result.url else { return false }
return isBookmarkable(url)
}
guard let matchRange = match?.range,
let swiftRange = Range(matchRange, in: decoded) else {
return nil
}
let candidate = String(decoded[swiftRange])
.trimmingCharacters(in: CharacterSet(charactersIn: " \n\t\r<>\"'.,;:)]】」"))
guard let url = URL(string: candidate), isBookmarkable(url) else { return nil }
return url.absoluteString
}
private static func isBookmarkable(_ url: URL) -> Bool {
guard let scheme = url.scheme?.lowercased(),
scheme == "http" || scheme == "https",
url.host?.isEmpty == false else {
return false
}
return true
}
private static func cleanedNotes(_ notes: String, excluding url: String) -> String {
let trimmed = decodeHTML(notes)
.replacingOccurrences(of: url, with: "")
.components(separatedBy: .newlines)
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
.joined(separator: "\n")
return String(trimmed.prefix(1800))
}
private static func decodeHTML(_ text: String) -> String {
text
.replacingOccurrences(of: "&amp;", with: "&")
.replacingOccurrences(of: "&lt;", with: "<")
.replacingOccurrences(of: "&gt;", with: ">")
.replacingOccurrences(of: "&quot;", with: "\"")
.replacingOccurrences(of: "&#39;", with: "'")
}
private static func shouldKeepNotes(for typeIdentifier: String?) -> Bool {
guard let typeIdentifier else { return true }
return !typeIdentifier.lowercased().contains("url")
}
}