Skip to content

Instantly share code, notes, and snippets.

@willbchang
Forked from yaakov-h/ReadingListReader.swift
Created January 10, 2021 08:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willbchang/4516619268a6826f21add9b613cb6dff to your computer and use it in GitHub Desktop.
Save willbchang/4516619268a6826f21add9b613cb6dff to your computer and use it in GitHub Desktop.
Read your Safari Reading List and dump to plain text
import Foundation
func fatalerror(_ text : String) {
fputs(text, __stderrp)
exit(-1)
}
struct ReadingListItem {
init(title: String?, previewText: String?, url: URL, dateAdded: Date) {
self.title = title
self.previewText = previewText
self.url = url
self.dateAdded = dateAdded
}
let title : String?
let previewText : String?
let url : URL
let dateAdded : Date
}
var items = [ReadingListItem]()
let outputPath = "/Users/yaakov/Sync/Personal/readinglist"
let libraryDirectory = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
if let
bookmarks = NSDictionary(contentsOfFile: "\(outputPath)/Bookmarks.plist"),
let children = bookmarks["Children"] as? [NSDictionary] {
for var item in children {
if item["WebBookmarkType"] as? String != "WebBookmarkTypeList" || item["Title"] as? String != "com.apple.ReadingList" {
continue
}
let readingListItems = item["Children"] as? [NSDictionary]
if let readingListItems = readingListItems {
for var currentItem in readingListItems {
let title = (currentItem["URIDictionary"] as? NSDictionary)?["title"] as? String
let uri = currentItem["URLString"] as? String
let rldata = currentItem["ReadingList"] as? NSDictionary
let preview = rldata?["PreviewText"] as? String
let date = rldata?["DateAdded"] as? Date
if let _ = title, let _ = uri {
print()
} else {
fatalerror("Missing title or uri for item.")
}
if date == nil {
fatalerror("Missing date for item.")
}
if let urlText = uri, let url = URL(string: urlText) {
let item = ReadingListItem(title: title, previewText: preview, url: url, dateAdded: date!)
items.append(item)
}
}
} else {
fatalerror("Could not find a Reading List bookmarks set.")
}
}
} else {
fatalerror("Unable to load Safari Bookmarks.")
}
let itemsByDomain = Dictionary(grouping: items, by: { $0.url.host?.lowercased() ?? "unknown" })
print("Found \(itemsByDomain.values.count) items across \(itemsByDomain.keys.count) domains.")
var domains = Array(itemsByDomain.keys)
for var domain in domains {
let domainItems = itemsByDomain[domain]!.sorted(by: { $0.dateAdded < $1.dateAdded })
var text = ""
for var item in domainItems {
text += item.dateAdded.description + "\n"
if let title = item.title {
text += title + "\n"
}
text += item.url.absoluteString + "\n"
if let preview = item.previewText {
text += preview + "\n"
}
text += "\n----\n\n"
}
try text.write(toFile: outputPath + "/" + domain + ".txt", atomically: true, encoding: .utf8)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment