-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtabby.rb
executable file
·101 lines (83 loc) · 3.19 KB
/
tabby.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
require "csv"
require "fileutils"
require "htmlbeautifier"
require "markaby"
require "sqlite3"
require "tempfile"
# Set export path
base = ARGV[0] && !ARGV[0].start_with?("-") ? File.expand_path(ARGV[0]) : File.expand_path("~/Desktop")
base = File.join(base, "tabgroups"); FileUtils.mkdir_p(base)
# Set library path
app = ARGV.include?("-stp") ? "SafariTechnologyPreview" : "Safari"
library = File.expand_path("~/Library/Containers/com.apple.#{app}/Data/Library/#{app}")
# Copy safari tabs into temporary file
original = File.expand_path("#{library}/SafariTabs.db")
temporary = Tempfile.new("SafariTabs.db"); FileUtils.cp(original, temporary.path)
# Export tab groups
begin
db = SQLite3::Database.open(temporary.path)
# Select tab groups from personal profile
personal = [:personal, "SELECT id, title FROM bookmarks WHERE type = 1 AND parent = 0 AND subtype == 0 AND num_children > 0 AND hidden == 0 ORDER BY id DESC"]
# Select tab groups from all other profiles
profiles = "SELECT id, title FROM bookmarks WHERE subtype = '2' and title != ''"
profiles = db.execute(profiles).map do |profile|
[profile[1].downcase.to_sym, "SELECT id, title FROM bookmarks WHERE parent = #{profile[0]} AND subtype == 0 AND num_children > 0 ORDER BY id DESC"]
end
# Export tab groups to CSV and HTML
groups = [personal]
groups << profiles.flatten unless profiles.empty?
groups.each do |profile|
profile, query = profile
tab_groups = db.execute(query)
profile_directory = File.join(base, profile.to_s)
FileUtils.mkdir_p(profile_directory)
# Export to CSV
CSV.open("#{profile_directory}/bookmarks.csv", "w") do |csv|
csv << ["Tab Group", "Bookmark", "URL"]
tab_groups.each do |group|
id, group = group
query = "SELECT title, url FROM bookmarks WHERE parent = #{id} AND title NOT IN ('TopScopedBookmarkList', 'Untitled', 'Start Page') ORDER BY order_index ASC"
bookmarks = db.execute(query)
bookmarks.each do |bookmark|
name, url = bookmark
csv << [group, name, url]
end
end
end
# Export to HTML
File.open("#{profile_directory}/bookmarks.html", "w") do |html|
# Add header
html.puts <<~HTML
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>#{profile.capitalize} Bookmarks</TITLE>
<H1>#{profile.capitalize} Bookmarks</H1>
HTML
# Add bookmarks
mab = Markaby::Builder.new
tab_groups.each do |group|
id, name = group
query = "SELECT title, url FROM bookmarks WHERE parent = #{id} AND title NOT IN ('TopScopedBookmarkList', 'Untitled', 'Start Page') ORDER BY order_index ASC"
bookmarks = db.execute(query)
mab.dt { h3 name }
mab.dd do
mab.dl do
bookmarks.each do |bookmark|
name, url = bookmark
mab.dt do
mab.a name, href: url
end
end
end
end
end
# Format markup and write to file
html.puts HtmlBeautifier.beautify(mab.to_s, tab_width: 2)
end
end
db.close
ensure
# Delete temporary file
temporary.close
temporary.unlink
end