forked from vitorgalvao/tiny-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpinboardurlupdate
More file actions
executable file
·101 lines (77 loc) · 3.29 KB
/
Copy pathpinboardurlupdate
File metadata and controls
executable file
·101 lines (77 loc) · 3.29 KB
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
#!/usr/bin/env ruby
require 'cgi'
require 'json'
require 'open-uri'
require 'open3'
require 'optparse'
def fail_message(url, message)
warn "\e[31m•\e[0m #{url}"
warn "⮑ #{message}"
end
def success_message(message)
puts "\e[32m•\e[0m #{message}"
end
# Options
ARGV.push('--help') if ARGV.empty?
options = {}
OptionParser.new do |opt|
opt.banner = <<~EOS
Substitute URLs of Pinboard bookmarks. Interacts with the files produced by "pinboardlinkcheck": text file, each line following the pattern 'old_url → new_url'.
Usage:
#{File.basename($PROGRAM_NAME)} [options] <file>
'token' options are compatible between pinboardbackup, pinboardlinkcheck, pinboardurlupdate, pinboardwaybackmachine
Options:
EOS
opt.on('-t <token>', '--token <token>', 'Your Pinboard API token.') { |t| options[:token] = t }
opt.on('-a', '--ask-for-token', 'Ask for your Pinboard API token on start.') { options[:ask_for_token] = true }
opt.on('-s', '--save-token', 'Save Pinboard API token to Keychain and exit (macOS-only). Use with "--token" or "--ask-for-token".') { options[:save_token] = true }
end.parse!
# Deal with token options
pinboard_token =
if options[:token]
options[:token]
elsif options[:ask_for_token]
puts <<~EOS
Please insert your api token (will not be echoed)
You can get it at https://pinboard.in/settings/password
EOS
print '> '
gets.chomp
else
Open3.capture2('security', 'find-generic-password', '-s', 'Pinboard API Token', '-w').first.strip
end
abort 'Cannot continue without a Pinboard token.' if pinboard_token.empty?
abort 'The Pinboard API token appears to be incorrect. Alternatively, Pinboard’s servers might be down.' if URI("https://api.pinboard.in/v1/user/api_token/?auth_token=#{pinboard_token}").open.nil?
system('security', 'add-generic-password', '-a', pinboard_token.split(':').first, '-s', 'Pinboard API Token', '-w', pinboard_token) if options[:save_token]
# Load file
links_file = ARGV[0]
abort 'You need to provide the path to a file.' if !File.file?(links_file)
# Update bookmarks
all_bookmarks = JSON.parse(URI("https://api.pinboard.in/v1/posts/all?auth_token=#{pinboard_token}&format=json").open.read)
File.readlines(links_file).each do |line|
urls = line.split('→').map(&:strip)
old_url = urls[0]
new_url = urls[1]
if urls.length != 2
puts 'Line is malformed. Skipping…'
next
end
bhash = all_bookmarks.detect { |hash| hash['href'] == old_url }
if bhash.nil?
fail_message(old_url, 'Did not find URL in account.')
next
end
bhash['href'] = new_url
bhash.transform_values! { |v| CGI.escape(v) }
add_bookmark_result = JSON.parse(URI("https://api.pinboard.in/v1/posts/add?url=#{bhash['href']}&description=#{bhash['description']}&extended=#{bhash['extended']}&tags=#{bhash['tags']}&dt=#{bhash['time']}&shared=#{bhash['shared']}&toread=#{bhash['toread']}&auth_token=#{pinboard_token}&format=json").open.read)['result_code']
if add_bookmark_result != 'done'
fail_message 'add updated', result
next
end
del_bookmark_result = JSON.parse(URI("https://api.pinboard.in/v1/posts/delete?url=#{CGI.escape(old_url)}&auth_token=#{pinboard_token}&format=json").open.read)['result_code']
if del_bookmark_result != 'done'
fail_message 'remove old', result
next
end
success_message line
end