booker 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/booker.rb +288 -74
- data/lib/bookmarks.rb +244 -65
- data/lib/config.rb +99 -26
- data/lib/consts.rb +103 -92
- metadata +23 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fc8148125669f4128e710ef78210347f90caf80f5753ffbacf48f0b78af6f851
|
|
4
|
+
data.tar.gz: 1deea2d2a8f289eaefb670c77cfe5a2a8696c2dcaafcbb96b990eda0e8269384
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b769f210cd3153dafe3240119044e742765bc260afcbf963daec319c135975799376446198fb9cecc68a3ad277ffb43fe33bc3529ad8af62a79cf6403ecfc577
|
|
7
|
+
data.tar.gz: b2c40993f4f25aac98a5a2549eba4f933e31d504c1f6f85245b075eda2ba2072f26154a97fded5dc2e429738f127fc90617d7d6f52b0ba35b1e17c5a333f6443
|
data/lib/booker.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# parse booker's command line args
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
|
|
2
|
+
require "yaml"
|
|
3
|
+
require "find"
|
|
4
|
+
require "json"
|
|
5
|
+
require "shellwords"
|
|
6
|
+
require "fileutils"
|
|
7
|
+
require_relative "bookmarks"
|
|
8
|
+
require_relative "config"
|
|
9
|
+
require_relative "consts"
|
|
10
10
|
|
|
11
11
|
# get booker opening command
|
|
12
12
|
class Booker
|
|
13
|
-
@version = "1.
|
|
13
|
+
@version = "1.2.0"
|
|
14
14
|
@@version = @version
|
|
15
15
|
|
|
16
16
|
class << self
|
|
@@ -18,27 +18,45 @@ class Booker
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
include Browser
|
|
21
|
+
|
|
21
22
|
def initialize(args)
|
|
22
23
|
parse args
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def parse(args)
|
|
26
|
-
# no args given, show
|
|
27
|
-
|
|
27
|
+
# no args given, show interactive bookmark selector
|
|
28
|
+
show_bookmarks if args.none?
|
|
28
29
|
|
|
29
30
|
# if arg starts with hyphen, parse option
|
|
30
|
-
parse_opt args if /^-.*/.match(args.first)
|
|
31
|
+
parse_opt args if /^-.*/.match?(args.first)
|
|
31
32
|
|
|
32
|
-
#
|
|
33
|
-
|
|
33
|
+
# separate bookmark IDs from other args
|
|
34
|
+
bookmark_ids = []
|
|
35
|
+
other_args = []
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
args.each do |arg|
|
|
38
|
+
if /^[0-9_]+$/.match?(arg) # bookmark ID (digits or underscore)
|
|
39
|
+
bookmark_ids << arg
|
|
40
|
+
else
|
|
41
|
+
other_args << arg
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# open all bookmarks first
|
|
46
|
+
unless bookmark_ids.empty?
|
|
47
|
+
open_bookmark bookmark_ids
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# then handle remaining args
|
|
51
|
+
unless other_args.empty?
|
|
52
|
+
if other_args.length == 1 && domain.match(other_args.first)
|
|
53
|
+
# single website URL
|
|
54
|
+
puts "opening website: " + other_args.first
|
|
55
|
+
openweb(prep(other_args.first))
|
|
56
|
+
else
|
|
57
|
+
# search for the rest
|
|
58
|
+
open_search(other_args.join(" ").strip)
|
|
59
|
+
end
|
|
42
60
|
end
|
|
43
61
|
end
|
|
44
62
|
|
|
@@ -56,7 +74,16 @@ class Booker
|
|
|
56
74
|
end
|
|
57
75
|
|
|
58
76
|
def openweb(url)
|
|
59
|
-
|
|
77
|
+
# Pass URL directly to browser without invoking shell
|
|
78
|
+
# This avoids issues with special characters like parentheses
|
|
79
|
+
browser_cmd = browse.strip
|
|
80
|
+
|
|
81
|
+
# Redirect stdout/stderr to suppress GTK warnings
|
|
82
|
+
success = system(browser_cmd, url, out: "/dev/null", err: "/dev/null")
|
|
83
|
+
|
|
84
|
+
unless success
|
|
85
|
+
puts "Warning: ".yel + "Failed to open URL (exit code: #{$?.exitstatus})"
|
|
86
|
+
end
|
|
60
87
|
end
|
|
61
88
|
|
|
62
89
|
# an array of ints, as bookmark ids
|
|
@@ -64,64 +91,114 @@ class Booker
|
|
|
64
91
|
id = bm.shift
|
|
65
92
|
url = Bookmarks.new.bookmark_url(id)
|
|
66
93
|
pexit "Failure:".red + " bookmark #{id} not found", 1 if url.nil?
|
|
67
|
-
puts
|
|
68
|
-
openweb(wrap(
|
|
94
|
+
puts "opening bookmark " + url + "..."
|
|
95
|
+
openweb(url) # No wrap() needed - system() handles it
|
|
69
96
|
open_bookmark bm unless bm.empty?
|
|
70
97
|
end
|
|
71
98
|
|
|
72
99
|
def open_search(term)
|
|
73
|
-
puts
|
|
100
|
+
puts "searching " + term + "..."
|
|
74
101
|
search = BConfig.new.searcher
|
|
75
|
-
term = term.
|
|
76
|
-
openweb(search +
|
|
102
|
+
term = term.tr(" ", "+")
|
|
103
|
+
openweb(search + term) # No shell escape needed - it's a URL
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def show_bookmarks
|
|
107
|
+
puts "Bookmarks:".grn + " (usage: booker <id> or booker <search>)"
|
|
108
|
+
puts ""
|
|
109
|
+
|
|
110
|
+
bm = Bookmarks.new("") # Get all bookmarks
|
|
111
|
+
allurls = bm.instance_variable_get(:@allurls)
|
|
112
|
+
|
|
113
|
+
if allurls.empty?
|
|
114
|
+
puts "No bookmarks found.".red
|
|
115
|
+
puts "Run: ".yel + "booker --install bookmarks".cyan
|
|
116
|
+
exit 0
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Calculate responsive column widths
|
|
120
|
+
term_width = `tput cols`.to_i
|
|
121
|
+
term_width = 100 if term_width == 0 # fallback
|
|
122
|
+
|
|
123
|
+
id_width = 10
|
|
124
|
+
remaining = term_width - id_width - 3 # 3 spaces between columns
|
|
125
|
+
|
|
126
|
+
folder_width = [remaining * 0.20, 15].max.to_i
|
|
127
|
+
title_width = [remaining * 0.30, 20].max.to_i
|
|
128
|
+
url_width = [remaining * 0.50, 30].max.to_i
|
|
129
|
+
|
|
130
|
+
# Display bookmarks in a readable format
|
|
131
|
+
allurls.each do |bookmark|
|
|
132
|
+
id_str = bookmark.id.to_s.window(id_width).grn
|
|
133
|
+
|
|
134
|
+
# Clean up folder display
|
|
135
|
+
folder = bookmark.folder.gsub(/^\|/, "") # Remove leading |
|
|
136
|
+
folder = (folder == "/") ? "[root]" : folder.chomp("/") # Show [root] for top-level
|
|
137
|
+
folder_str = folder.window(folder_width).blu
|
|
138
|
+
|
|
139
|
+
title_str = bookmark.title.window(title_width).yel
|
|
140
|
+
url_str = bookmark.url.window(url_width)
|
|
141
|
+
|
|
142
|
+
puts "#{id_str} #{folder_str} #{title_str} #{url_str}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
puts ""
|
|
146
|
+
puts "Found #{allurls.length} bookmarks".grn
|
|
147
|
+
puts ""
|
|
148
|
+
puts "Examples:".yel
|
|
149
|
+
puts " #{"booker #{allurls.first.id}".ljust(20).cyan} # Open first bookmark"
|
|
150
|
+
puts " #{"booker github".ljust(20).cyan} # Search bookmarks for 'github'"
|
|
151
|
+
puts " #{"booker --help".ljust(20).cyan} # Show help"
|
|
152
|
+
|
|
153
|
+
exit 0
|
|
77
154
|
end
|
|
78
155
|
|
|
79
156
|
# parse and execute any command line options
|
|
80
157
|
def parse_opt(args)
|
|
81
|
-
valid_opts = %w
|
|
82
|
-
|
|
158
|
+
valid_opts = %w[--version -v --install -i --help -h
|
|
159
|
+
--complete -c --bookmark -b --search -s]
|
|
83
160
|
|
|
84
161
|
nextarg = args.shift
|
|
85
|
-
errormsg =
|
|
86
|
-
pexit errormsg, 1 if !
|
|
162
|
+
errormsg = "Error: ".red + "unrecognized option #{nextarg}"
|
|
163
|
+
pexit errormsg, 1 if !(valid_opts.include? nextarg)
|
|
87
164
|
|
|
88
165
|
# forced bookmarking
|
|
89
|
-
if nextarg ==
|
|
166
|
+
if nextarg == "--bookmark" || nextarg == "-b"
|
|
90
167
|
if args.first.nil?
|
|
91
|
-
pexit
|
|
168
|
+
pexit "Error: ".red + "booker --bookmark expects bookmark id", 1
|
|
92
169
|
else
|
|
93
170
|
open_bookmark args
|
|
94
171
|
end
|
|
95
172
|
end
|
|
96
173
|
|
|
97
174
|
# autocompletion
|
|
98
|
-
if nextarg ==
|
|
99
|
-
allargs = args.join(
|
|
175
|
+
if nextarg == "--complete" || nextarg == "-c"
|
|
176
|
+
allargs = args.join(" ")
|
|
100
177
|
bm = Bookmarks.new(allargs)
|
|
101
178
|
bm.autocomplete
|
|
102
179
|
end
|
|
103
180
|
|
|
104
181
|
# installation
|
|
105
|
-
if nextarg ==
|
|
182
|
+
if nextarg == "--install" || nextarg == "-i"
|
|
106
183
|
if !args.empty?
|
|
107
184
|
install(args)
|
|
108
185
|
else # do everything
|
|
109
|
-
install(%w
|
|
186
|
+
install(%w[completion config bookmarks])
|
|
110
187
|
end
|
|
111
188
|
end
|
|
112
189
|
|
|
113
190
|
# forced searching
|
|
114
|
-
if nextarg ==
|
|
115
|
-
pexit
|
|
116
|
-
allargs = args.join(
|
|
191
|
+
if nextarg == "--search" || nextarg == "-s"
|
|
192
|
+
pexit "--search requires an argument", 1 if args.empty?
|
|
193
|
+
allargs = args.join(" ")
|
|
117
194
|
open_search allargs
|
|
118
195
|
end
|
|
119
196
|
|
|
120
197
|
# print version information
|
|
121
|
-
version if nextarg ==
|
|
198
|
+
version if nextarg == "--version" || nextarg == "-v"
|
|
122
199
|
|
|
123
200
|
# needs some help
|
|
124
|
-
helper if nextarg ==
|
|
201
|
+
helper if nextarg == "--help" || nextarg == "-h"
|
|
125
202
|
|
|
126
203
|
exit 0 # dont parse_arg
|
|
127
204
|
end # parse_opt
|
|
@@ -130,11 +207,11 @@ class Booker
|
|
|
130
207
|
target = args.shift
|
|
131
208
|
exit 0 if target.nil?
|
|
132
209
|
|
|
133
|
-
if /comp/i.match(target) # completion installation
|
|
210
|
+
if /comp/i.match?(target) # completion installation
|
|
134
211
|
install_completion
|
|
135
|
-
elsif /book/i.match(target) # bookmarks installation
|
|
212
|
+
elsif /book/i.match?(target) # bookmarks installation
|
|
136
213
|
install_bookmarks
|
|
137
|
-
elsif /conf/i.match(target) # default config file generation
|
|
214
|
+
elsif /conf/i.match?(target) # default config file generation
|
|
138
215
|
install_config
|
|
139
216
|
else # unknown argument passed into install
|
|
140
217
|
pexit "Failure: ".red + "unknown installation option (#{target})", 1
|
|
@@ -146,64 +223,201 @@ class Booker
|
|
|
146
223
|
def install_completion
|
|
147
224
|
# check if zsh is even installed for this user
|
|
148
225
|
begin
|
|
149
|
-
fpath = `zsh -c 'echo $fpath'`.split(
|
|
226
|
+
fpath = `zsh -c 'echo $fpath'`.split(" ")
|
|
150
227
|
rescue
|
|
151
228
|
pexit "Failure: ".red + "zsh is probably not installed, could not find $fpath", 1
|
|
152
229
|
end
|
|
153
230
|
|
|
154
|
-
#
|
|
155
|
-
|
|
231
|
+
# Try user-writable directories first, then system directories
|
|
232
|
+
user_home = ENV["HOME"]
|
|
233
|
+
writable_dirs = fpath.select do |fp|
|
|
234
|
+
fp.start_with?(user_home) && File.directory?(fp) && File.writable?(fp)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# If no user-writable directories, try to create one
|
|
238
|
+
if writable_dirs.empty?
|
|
239
|
+
user_completion_dir = File.join(user_home, ".zsh", "completion")
|
|
156
240
|
begin
|
|
157
|
-
|
|
241
|
+
FileUtils.mkdir_p(user_completion_dir)
|
|
242
|
+
writable_dirs << user_completion_dir
|
|
243
|
+
puts "Created user completion directory: #{user_completion_dir}".yel
|
|
244
|
+
|
|
245
|
+
# Auto-configure .zshrc if it exists
|
|
246
|
+
zshrc = File.join(user_home, ".zshrc")
|
|
247
|
+
if File.exist?(zshrc)
|
|
248
|
+
zshrc_content = File.read(zshrc)
|
|
249
|
+
if zshrc_content.include?(".zsh/completion")
|
|
250
|
+
puts "~/.zshrc already configured".grn
|
|
251
|
+
else
|
|
252
|
+
File.open(zshrc, "a") do |f|
|
|
253
|
+
f.puts "\n# Booker completion"
|
|
254
|
+
f.puts "fpath=(~/.zsh/completion $fpath)"
|
|
255
|
+
f.puts "autoload -Uz compinit && compinit"
|
|
256
|
+
end
|
|
257
|
+
puts "Added completion to ~/.zshrc".grn
|
|
258
|
+
puts "Run: ".yel + "source ~/.zshrc".cyan + " to activate"
|
|
259
|
+
end
|
|
260
|
+
else
|
|
261
|
+
puts "Add this to your ~/.zshrc: ".yel + "fpath=(~/.zsh/completion $fpath)".cyan
|
|
262
|
+
end
|
|
263
|
+
rescue => e
|
|
264
|
+
# Couldn't create user dir, try system dirs as fallback
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Try writable directories first, then all directories as fallback
|
|
269
|
+
dirs_to_try = writable_dirs + fpath.reject { |fp| writable_dirs.include?(fp) }
|
|
270
|
+
|
|
271
|
+
success = false
|
|
272
|
+
dirs_to_try.each do |fp|
|
|
273
|
+
next unless File.directory?(fp)
|
|
274
|
+
|
|
275
|
+
begin
|
|
276
|
+
completion_file = File.join(fp, "_booker")
|
|
277
|
+
File.write(completion_file, COMPLETION)
|
|
158
278
|
system "zsh -c 'autoload -U _booker'"
|
|
159
279
|
puts "Success: ".grn + "installed zsh autocompletion in #{fp}"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
280
|
+
success = true
|
|
281
|
+
break
|
|
282
|
+
rescue => e
|
|
283
|
+
# Try next directory silently
|
|
163
284
|
end
|
|
164
285
|
end
|
|
286
|
+
|
|
287
|
+
unless success
|
|
288
|
+
puts "Warning: ".yel + "Could not install ZSH completion to any directory in $fpath"
|
|
289
|
+
puts "Try manually: ".grn + "mkdir -p ~/.zsh/completion && booker --install completion"
|
|
290
|
+
end
|
|
165
291
|
end
|
|
166
292
|
|
|
167
293
|
def install_bookmarks
|
|
168
294
|
# locate bookmarks file, show user, write to config?
|
|
169
|
-
puts
|
|
295
|
+
puts "searching for chrome and firefox bookmarks..."
|
|
170
296
|
begin
|
|
171
|
-
bms = [] # look for bookmarks
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
297
|
+
bms = [] # look for bookmarks with type info
|
|
298
|
+
|
|
299
|
+
# Search for Chrome bookmarks
|
|
300
|
+
["Library/Application Support/Google/Chrome",
|
|
301
|
+
"AppData/Local/Google/Chrome/User Data/Default",
|
|
302
|
+
".config/chromium/Default",
|
|
303
|
+
".config/google-chrome/Default",
|
|
304
|
+
"snap/chromium/common/chromium",
|
|
305
|
+
"snap/chromium/current/.config/chromium"].each do |f|
|
|
306
|
+
home = File.join(ENV["HOME"], f)
|
|
178
307
|
next if !FileTest.directory?(home)
|
|
179
308
|
Find.find(home) do |file|
|
|
180
|
-
|
|
309
|
+
if /chrom.*bookmarks/i.match?(file)
|
|
310
|
+
bms << {path: file, type: :chrome}
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Search for Firefox bookmarks
|
|
316
|
+
firefox_paths = [
|
|
317
|
+
".mozilla/firefox", # Linux
|
|
318
|
+
"snap/firefox/common/.mozilla/firefox", # Linux (snap)
|
|
319
|
+
"Library/Application Support/Firefox", # macOS
|
|
320
|
+
"AppData/Roaming/Mozilla/Firefox" # Windows
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
firefox_paths.each do |f|
|
|
324
|
+
firefox_base = File.join(ENV["HOME"], f)
|
|
325
|
+
next if !FileTest.directory?(firefox_base)
|
|
326
|
+
|
|
327
|
+
profiles_ini = File.join(firefox_base, "profiles.ini")
|
|
328
|
+
next if !File.exist?(profiles_ini)
|
|
329
|
+
|
|
330
|
+
# Parse profiles.ini to find Firefox profiles
|
|
331
|
+
parse_firefox_profiles(profiles_ini, firefox_base).each do |db_path|
|
|
332
|
+
bms << {path: db_path, type: :firefox}
|
|
181
333
|
end
|
|
182
334
|
end
|
|
183
335
|
|
|
184
336
|
if bms.empty? # no bookmarks found
|
|
185
|
-
puts "Failure: ".red +
|
|
337
|
+
puts "Failure: ".red + "bookmarks file could not be found."
|
|
186
338
|
raise
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
puts
|
|
339
|
+
elsif bms.length == 1
|
|
340
|
+
# Auto-select if only one source found
|
|
341
|
+
selected = bms.first[:path]
|
|
342
|
+
type_label = (bms.first[:type] == :chrome) ? "[Chrome]" : "[Firefox]"
|
|
343
|
+
puts "Found bookmark source: #{type_label} #{selected}".yel
|
|
344
|
+
puts "Selected: ".yel + selected
|
|
192
345
|
BConfig.new.write(:bookmarks, selected)
|
|
193
346
|
puts "Success: ".grn + "config file updated with your bookmarks"
|
|
347
|
+
else # have user select a file
|
|
348
|
+
puts "select bookmarks source: "
|
|
349
|
+
|
|
350
|
+
# Offer "ALL" as first option if multiple sources found
|
|
351
|
+
puts "0".grn + " - " + "[ALL SOURCES]".cyan + " (search across all browsers)"
|
|
352
|
+
offset = 1
|
|
353
|
+
|
|
354
|
+
bms.each_with_index do |bm, i|
|
|
355
|
+
type_label = (bm[:type] == :chrome) ? "[Chrome]".yel : "[Firefox]".blu
|
|
356
|
+
puts (i + offset).to_s.grn + " - " + type_label + " " + bm[:path]
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
input = gets
|
|
360
|
+
raise "No input provided" if input.nil?
|
|
361
|
+
selection = input.chomp.to_i
|
|
362
|
+
|
|
363
|
+
if selection == 0
|
|
364
|
+
# User selected "ALL" - save array of all paths
|
|
365
|
+
all_paths = bms.map { |bm| bm[:path] }
|
|
366
|
+
puts "Selected: ".yel + "All sources (#{bms.length} bookmark files)"
|
|
367
|
+
BConfig.new.write(:bookmarks, all_paths)
|
|
368
|
+
puts "Success: ".grn + "config file updated to search all bookmark sources"
|
|
369
|
+
else
|
|
370
|
+
# User selected single source
|
|
371
|
+
actual_index = selection - 1
|
|
372
|
+
selected = bms[actual_index][:path]
|
|
373
|
+
puts "Selected: ".yel + selected
|
|
374
|
+
BConfig.new.write(:bookmarks, selected)
|
|
375
|
+
puts "Success: ".grn + "config file updated with your bookmarks"
|
|
376
|
+
end
|
|
194
377
|
end
|
|
195
|
-
rescue
|
|
378
|
+
rescue => e
|
|
196
379
|
puts e.message
|
|
197
380
|
pexit "Failure: ".red + "could not add bookmarks to config file ~/.booker", 1
|
|
198
381
|
end
|
|
199
382
|
end
|
|
200
383
|
|
|
201
|
-
def
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
384
|
+
def parse_firefox_profiles(ini_path, firefox_base)
|
|
385
|
+
profiles = []
|
|
386
|
+
current_profile = {}
|
|
387
|
+
|
|
388
|
+
File.readlines(ini_path).each do |line|
|
|
389
|
+
line = line.strip
|
|
390
|
+
|
|
391
|
+
# New profile section
|
|
392
|
+
if line.start_with?("[Profile")
|
|
393
|
+
# Save previous profile if it had a path
|
|
394
|
+
if current_profile[:path]
|
|
395
|
+
db_path = File.join(firefox_base, current_profile[:path], "places.sqlite")
|
|
396
|
+
profiles << db_path if File.exist?(db_path)
|
|
397
|
+
end
|
|
398
|
+
current_profile = {}
|
|
399
|
+
|
|
400
|
+
# Parse key=value pairs
|
|
401
|
+
elsif line.include?("=")
|
|
402
|
+
key, value = line.split("=", 2).map(&:strip)
|
|
403
|
+
current_profile[:path] = value if key == "Path"
|
|
404
|
+
current_profile[:name] = value if key == "Name"
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Don't forget the last profile
|
|
409
|
+
if current_profile[:path]
|
|
410
|
+
db_path = File.join(firefox_base, current_profile[:path], "places.sqlite")
|
|
411
|
+
profiles << db_path if File.exist?(db_path)
|
|
207
412
|
end
|
|
413
|
+
|
|
414
|
+
profiles
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def install_config
|
|
418
|
+
BConfig.new.write
|
|
419
|
+
puts "Success: ".grn + "example config file written to ~/.booker"
|
|
420
|
+
rescue
|
|
421
|
+
pexit "Failure: ".red + "could not write example config file to ~/.booker", 1
|
|
208
422
|
end
|
|
209
423
|
end
|