-
-
Notifications
You must be signed in to change notification settings - Fork 91
/
example_plugin.rb
211 lines (188 loc) · 6.79 KB
/
example_plugin.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# frozen_string_literal: true
# title: Export plugin example
# description: Speak the most recent entry (macOS)
# author: Brett Terpstra
# url: https://brettterpstra.com
# Example
#
# doing show -o sayit
#
# ## Configuration
#
# Change what the plugin says by generating a template with
# `doing template --type say`, saving it to a file, and
# putting the path to that file in `export_templates->say` in
# config.yml.
#
# export_templates:
# say: /path/to/template.txt
#
# Use a different voice by adding a `say_voice` key to your
# config.yml. Use `say -v ?` to see available voices.
#
# say_voice: Zarvox
module Doing
##
## Plugin class
##
class SayExport
include Doing::Util
#-------------------------------------------------------
## Plugin Settings. A plugin must have a self.settings
## method that returns a hash with plugin settings.
##
## trigger: (required) Regular expression to match
## FORMAT when used with `--output FORMAT`. Registered
## name of plugin must be able to match the trigger, but
## alternatives can be included
##
## templates: (optional) Array of templates this plugin
## can export (plugin must have :template method)
##
## Each template is a hash containing:
## - name: display name for template
## - trigger: regular expression for
## `template --type FORMAT`
## - format: a descriptor of the file format (erb, haml, stylus, etc.)
## - filename: a default filename used when the template is written to disk
##
## If a template is included, a config key will
## automatically be added for the user to override
## The config key will be available at:
##
## Doing.config.settings['export_templates'][PLUGIN_NAME]
##
## config: (optional) A Hash which will be
## added to the main configuration in the plugins section.
## Options defined here are included when config file is
## created or updated with `config --update`. Use this to
## add new configuration keys, not to override existing
## ones.
##
## The configuration keys will be available at:
##
## Doing.config.settings['plugins'][PLUGIN_NAME][KEY]
##
## Method to return plugin settings (required)
##
## @return Hash of settings for this plugin
##
def self.settings
{
trigger: 'say(?:it)?',
templates: [
{ name: 'say', trigger: 'say(?:it)?', format: 'text', filename: 'say.txt' }
],
config: {
'say_voice' => 'Fiona'
}
}
end
#-------------------------------------------------------
## Output a template. Only required if template(s) are
## included in settings. The method should return a
## string (not output it to the STDOUT).
##
## Method to return template (optional)
##
## @param trigger The trigger passed to the
## template function. When this
## method defines multiple
## templates, the trigger can be
## used to determine which one is
## output.
##
## @return [String] template contents
##
def self.template(trigger)
return unless trigger =~ /^say(it)?$/
'On %date, you were %title, recorded in section %section%took'
end
##
## Render data received from an output
## command
##
## @param wwid The wwid object with config
## and public methods
## @param items An array of items to be output
## { <Date>date, <String>title,
## <String>section, <Array>note }
## @param variables Additional variables including
## flags passed to command
## (variables[:options])
##
## @return [String] Rendered output
##
def self.render(wwid, items, variables: {})
return unless items.good?
config = Doing.config.settings
# the :options key includes the flags passed to the
# command that called the plugin use `puts
# variables.inspect` to see properties and methods
# when run
opt = variables[:options]
# This plugin just grabs the last item in the `items`
# list (which could be the oldest or newest, depending
# on the sort order of the command that called the
# plugin). Most of the time you'll want to use :each
# or :map to generate output.
i = items[-1]
# Format the item. Items are an object with 4 methods:
# date, title, section (parent section), and note.
# Start time is in item.date. The wwid object has some
# methods for calculation and formatting, including
# wwid.item.end_date to convert the @done timestamp to
# an end date.
if opt[:times]
interval = i.interval
if interval
took = '. You finished on '
finished_at = i.end_date
took += finished_at.strftime('%A %B %e at %I:%M%p')
took += ' and it took'
took += interval.time_string(format: :natural)
end
end
date = i.date.strftime('%A %B %e at %I:%M%p')
title = i.title.gsub(/@/, 'hashtag ')
tpl = template('say')
if config['export_templates'].key?('say')
cfg_tpl = config['export_templates']['say']
tpl = cfg_tpl if cfg_tpl.good?
end
output = tpl.dup
output.gsub!(/%date/, date)
output.gsub!(/%title/, title)
output.gsub!(/%section/, i.section)
output.gsub!(/%took/, took || '')
# Debugging output
# warn "Saying: #{output}"
# To provide results on the command line after the
# command runs, use Doing.logger, which responds to
# :debug, :info, :warn, and :error. e.g.:
#
# Doing.logger.info("This plugin has run")
# Doing.logger.error("This message will be displayed even if run in --quiet mode.")
#
# Results are
# provided on STDERR unless doing is run with
# `--stdout` or non-interactively.
Doing.logger.info('Spoke the last entry. Did you hear it?')
# This export runs a command for fun, most plugins won't
voice = config['plugins']['say']['say_voice'] || 'Alex'
`say -v "#{voice}" "#{output}"`
# Return the result (don't output to terminal with puts or print)
output
end
# Register the plugin with doing.
# Doing::Plugins.register 'NAME', TYPE, Class
#
# Name should be lowercase, no spaces
#
# TYPE is :import or :export
#
# Class is the plugin class (e.g. Doing::SayExport), or
# self if called within the class
Doing::Plugins.register 'say', :export, self
end
end