-
-
Save willbchang/4516619268a6826f21add9b613cb6dff to your computer and use it in GitHub Desktop.
Read your Safari Reading List and dump to plain text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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