-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsearch
executable file
·97 lines (79 loc) · 2 KB
/
search
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
#!/usr/bin/ruby
# Download Calendly event types from API and let the user choose 1
require 'uri'
require 'open-uri'
require 'json'
API_KEY_FILE = File.join(ENV.fetch('HOME'), ENV.fetch('config_api_key_file'))
def emit(items)
$stderr.puts items.inspect
puts JSON.dump(items: items)
exit
end
def log(arg)
$stderr.puts arg.inspect
end
def offer_auth
emit [
{
arg: 'add-api-key',
title: 'Add your API key',
},
{
arg: 'browse-for-api-key',
title: 'Get your API key from calendly.com',
},
]
end
def icon_path(color_rgb)
"./icons/event-type-color-#{color_rgb.sub('#', '')}.png".tap do |path|
if !File.exist?(path)
log "Icon does not exist for color: #{color_rgb}"
end
end
end
offer_auth unless File.exist?(API_KEY_FILE)
api_key = File.read(API_KEY_FILE)
api_uri = URI.parse('https://calendly.com/api/v1/users/me/event_types')
response = api_uri.open('X-TOKEN' => api_key) do |f|
status, message = f.status
log status: status, message: message
offer_auth unless status == "200"
f.read
end
raw_event_types = JSON.parse(response).fetch('data')
# Enable fuzzy search by listing all n-grams of searchable fields
module MatchString
module_function
def ngrams(str, n)
str.downcase.each_char.each_cons(n).to_a.map(&:join).join(' ')
end
def allgrams(str)
(1..str.length).map { |n| ngrams(str, n) }.join(' ')
end
def call(*attrs)
allgrams(attrs.map(&:to_s).join(' '))
end
end
items = raw_event_types.map do |raw_event_type|
attr = ->(key) { raw_event_type.fetch('attributes').fetch(key) }
next unless attr['active']
subtitle = [
"#{attr['duration']}m",
attr['slug'],
attr['description'],
].compact.join(', ')
{
uid: raw_event_type.fetch('id'),
title: attr['name'],
arg: attr['url'],
icon: { path: icon_path(attr['color']) },
subtitle: subtitle,
match: MatchString.call(
attr['name'],
attr['description'],
attr['duration'],
attr['slug'],
),
}
end.compact
emit items