sifttter-redux 0.5.4 → 0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac0c51854f8d85fe836c9bec7be780a4d149ef55
4
- data.tar.gz: 83c7b28fe6fae8fae9c55d1e95c9b845a1fa5817
3
+ metadata.gz: 6967ac35281de5c0dd08146937c43fee382de50d
4
+ data.tar.gz: 67c9c4c56ceeea7e137cf351642b7beaf4cc6862
5
5
  SHA512:
6
- metadata.gz: 952c9d9cc4d4e68ced1d567278d4294fb5551ad7c5f9ff11f9fc4ba1a8ec847137dad74f29124ae45d3d3bf6db51cf13e6a6ceb6857f96d49a3e02b6b2895b3f
7
- data.tar.gz: 3f8c244c3a6872727f775a2973ecbadfdbb1ad46730cae3f05f742bab981b0f6835cd8af6dc641f86fee6447f3c599852700fae9b58f4f827491f3d6ef2c84ef
6
+ metadata.gz: 5f270d0de834059c6eb902f8952266614ae55f081ce4c415f50b3ccae13edeb9013c4fda4c36e86ddf4d9945132d7e5c98fa42a723faa4a07207b7f39bf564c3
7
+ data.tar.gz: 1b3494e3085c982ea906e36480ad7badf9f9f6ff982d07c7bf630151948b1c16baaa29a88a621b5373e5d6fb730f07fb43ce79dfe5b980559c6aa47596a57e4c
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ Gemfile.lock
3
3
  .DS_Store
4
4
  results.html
5
5
  *.gem
6
+ features/3.execution.feature
data/.travis.yml CHANGED
@@ -3,4 +3,8 @@ rvm:
3
3
  - 2.1.0
4
4
  - 2.0.0
5
5
  - 1.9.3
6
- - jruby-19mode
6
+ - jruby-19mode
7
+ env:
8
+ - TEST_SUITE=1.ui.feature
9
+ script:
10
+ - bundle exec cucumber -f progress -r features features/$TEST_SUITE
data/Gemfile CHANGED
@@ -1,2 +1,3 @@
1
1
  source 'https://rubygems.org'
2
+
2
3
  gemspec
data/Rakefile CHANGED
@@ -1,22 +1,25 @@
1
1
  require 'rake/clean'
2
2
  require 'rubygems'
3
- require 'rubygems/package_task'
4
- require 'rdoc/task'
5
- require 'cucumber'
6
- require 'cucumber/rake/task'
7
- Rake::RDocTask.new do |rd|
8
- rd.main = "README.rdoc"
9
- rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
10
- rd.title = 'Your application title'
3
+
4
+ def version
5
+ contents = File.read File.expand_path('../lib/sifttter-redux/constants.rb', __FILE__)
6
+ contents[/VERSION = '([^']+)'/, 1]
11
7
  end
12
8
 
13
- spec = eval(File.read('sifttter_redux.gemspec'))
9
+ spec = eval(File.read('sifttter-redux.gemspec'))
14
10
 
15
- Gem::PackageTask.new(spec) do |pkg|
11
+ require 'rake/testtask'
12
+ desc 'Run unit tests'
13
+ Rake::TestTask.new do |t|
14
+ t.libs << "test"
15
+ t.test_files = FileList['test/*_test.rb']
16
16
  end
17
+
18
+ require 'cucumber'
19
+ require 'cucumber/rake/task'
17
20
  CUKE_RESULTS = 'results.html'
18
21
  CLEAN << CUKE_RESULTS
19
- desc 'Run features'
22
+ desc 'Run Cucumber features'
20
23
  Cucumber::Rake::Task.new(:features) do |t|
21
24
  opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
22
25
  opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
@@ -24,21 +27,71 @@ Cucumber::Rake::Task.new(:features) do |t|
24
27
  t.fork = false
25
28
  end
26
29
 
27
- desc 'Run features tagged as work-in-progress (@wip)'
28
- Cucumber::Rake::Task.new('features:wip') do |t|
29
- tag_opts = ' --tags ~@pending'
30
- tag_opts = ' --tags @wip'
31
- t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
32
- t.fork = false
30
+ desc "Release Sifttter Redux version #{ version }"
31
+ task :release => :build do
32
+ unless `git branch` =~ /^\* master$/
33
+ puts "You must be on the master branch to release!"
34
+ exit!
35
+ end
36
+
37
+ sh "git commit --allow-empty -a -m 'Release #{ version }'"
38
+ sh "git tag v#{ version }"
39
+ sh "git push origin master"
40
+ sh "git push origin v#{ version }"
41
+ sh "gem push pkg/sifttter-redux-#{ version }.gem"
33
42
  end
34
43
 
35
- task :cucumber => :features
36
- task 'cucumber:wip' => 'features:wip'
37
- task :wip => 'features:wip'
38
- require 'rake/testtask'
39
- Rake::TestTask.new do |t|
40
- t.libs << "test"
41
- t.test_files = FileList['test/*_test.rb']
44
+ desc "Build the gem"
45
+ task :build do
46
+ p version
47
+ FileUtils.mkdir_p "pkg"
48
+ sh "gem build sifttter-redux.gemspec"
49
+ FileUtils.mv("./sifttter-redux-#{ version }.gem", "pkg")
42
50
  end
43
51
 
44
- task :default => [:test]
52
+ task :default => [:test, :features]
53
+
54
+ # require 'rake/clean'
55
+ # require 'rubygems'
56
+ # require 'rubygems/package_task'
57
+ # require 'rdoc/task'
58
+ # require 'cucumber'
59
+ # require 'cucumber/rake/task'
60
+ # Rake::RDocTask.new do |rd|
61
+ # rd.main = "README.rdoc"
62
+ # rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
63
+ # rd.title = 'Your application title'
64
+ # end
65
+ #
66
+ # spec = eval(File.read('sifttter_redux.gemspec'))
67
+ #
68
+ # Gem::PackageTask.new(spec) do |pkg|
69
+ # end
70
+ # CUKE_RESULTS = 'results.html'
71
+ # CLEAN << CUKE_RESULTS
72
+ # desc 'Run features'
73
+ # Cucumber::Rake::Task.new(:features) do |t|
74
+ # opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
75
+ # opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
76
+ # t.cucumber_opts = opts
77
+ # t.fork = false
78
+ # end
79
+ #
80
+ # desc 'Run features tagged as work-in-progress (@wip)'
81
+ # Cucumber::Rake::Task.new('features:wip') do |t|
82
+ # tag_opts = ' --tags ~@pending'
83
+ # tag_opts = ' --tags @wip'
84
+ # t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
85
+ # t.fork = false
86
+ # end
87
+ #
88
+ # task :cucumber => :features
89
+ # task 'cucumber:wip' => 'features:wip'
90
+ # task :wip => 'features:wip'
91
+ # require 'rake/testtask'
92
+ # Rake::TestTask.new do |t|
93
+ # t.libs << "test"
94
+ # t.test_files = FileList['test/*_test.rb']
95
+ # end
96
+ #
97
+ # task :default => [:test, :features]
data/bin/srd CHANGED
@@ -32,12 +32,14 @@
32
32
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33
33
  # OTHER DEALINGS IN THE SOFTWARE.
34
34
  #--------------------------------------------------------------------
35
+ require 'cliutils'
35
36
  require 'gli'
36
- require 'sifttter_redux'
37
+ require 'sifttter-redux'
37
38
  require 'securerandom'
38
39
 
40
+ include CLIUtils::Configuration
41
+ include CLIUtils::Messenging
39
42
  include GLI::App
40
- include SifttterRedux
41
43
 
42
44
  # ======================================================
43
45
  # App Info
@@ -48,7 +50,7 @@ program_desc 'Sifttter Redux
48
50
  smart installation and automated running on a standalone
49
51
  *NIX device (such as a Raspberry Pi).'
50
52
 
51
- version VERSION
53
+ version SifttterRedux::VERSION
52
54
 
53
55
  # ======================================================
54
56
  # Global Flags and Switches
@@ -61,44 +63,55 @@ switch([:verbose], desc: 'Turns on verbose output')
61
63
  pre do |global, command, options, args|
62
64
 
63
65
  # Load SifttterRedux configuration module.
64
- Configuration::load(SRD_CONFIG_FILEPATH)
66
+ load_configuration(SifttterRedux::DEFAULT_SRD_CONFIG_FILEPATH)
67
+ file_logger = Logger.new(SifttterRedux::DEFAULT_SRD_LOG_FILEPATH)
68
+ file_logger.level = LOG_LEVELS[configuration.sifttter_redux[:log_level] || 'DEBUG']
69
+ messenger.attach(LOGFILE: file_logger)
65
70
 
66
- # Set up logging.
67
- CLIMessage::activate_logging
68
- CLIMessage::log_level(Configuration::sifttter_redux[:log_level] || Logger::WARN)
71
+ if File.exists?(SifttterRedux::DEFAULT_SRD_CONFIG_FILEPATH)
72
+ # Check to see if there is a new config file version
73
+ # to be installed.
74
+ c_version = Gem::Version.new(configuration.sifttter_redux[:version])
75
+ l_version = Gem::Version.new(SifttterRedux::NEWEST_CONFIG_VERSION)
69
76
 
70
- if File.exists?(SRD_CONFIG_FILEPATH)
71
- current_version = Gem::Version.new(Configuration::sifttter_redux[:version])
72
- last_config_change_version = Gem::Version.new(NEWEST_CONFIG_VERSION)
77
+ messenger.debug { "Current gem version: #{ c_version }" }
78
+ messenger.debug { "Last version with config change: #{ l_version }" }
73
79
 
74
80
  # If the config file needs updating, force the user to do that first.
75
- if Configuration::sifttter_redux[:version].nil? || current_version < last_config_change_version
76
- CLIMessage::info('This version needs to make some config changes.')
77
- CLIMessage::info("Don't worry; when prompted, your current values for")
78
- CLIMessage::info("existing config options will be presented (so it'll")
79
- CLIMessage::info('be easier to fly through the upgrade).')
80
- CLIMessage::prompt('Press enter to continue')
81
- SifttterRedux::init(true)
81
+ if configuration.sifttter_redux[:version].nil? || c_version < l_version
82
+ SifttterRedux.update_config_file
82
83
  exit!(0)
83
84
  end
84
85
  else
85
86
  # Force the user to init if they try to run any command other than `init` first.
86
- SifttterRedux::init(true)
87
+ SifttterRedux.init(true)
87
88
  exit!(0)
88
89
  end
89
90
 
90
91
  true
91
92
  end
92
93
 
94
+ post do |global,command,options,args|
95
+ # Post logic here
96
+ # Use skips_post before a command to skip this
97
+ # block on that command only
98
+ end
99
+
100
+ on_error do |exception|
101
+ messenger.error(exception.to_s)
102
+ exit!(1)
103
+ true
104
+ end
105
+
93
106
  # ======================================================
94
107
  # Commands
95
108
  # ======================================================
96
109
  # ------------------------------------------------------
97
110
  # exec command
98
111
  #
99
- # Executes the script.
112
+ # Executes the app.
100
113
  # ------------------------------------------------------
101
- desc 'Execute the script'
114
+ desc 'Execute the app'
102
115
  command :exec do |c|
103
116
  c.flag([:f], desc: 'Run catch-up mode with this start date')
104
117
  c.flag([:n], desc: 'Run catch-up mode for the last N days')
@@ -113,49 +126,44 @@ command :exec do |c|
113
126
  c.action do |global_options, options, args|
114
127
  SifttterRedux.verbose = global_options[:verbose] || options[:verbose]
115
128
 
116
- begin
117
- dates = SifttterRedux::get_dates_from_options(options)
118
- unless dates.nil?
119
- first_date = dates.first
120
- second_date = dates.reverse_each.first
121
-
122
- date_string = first_date.strftime('%B %d, %Y')
123
- date_string << " to #{ second_date.strftime('%B %d, %Y') }" if first_date != second_date
124
- CLIMessage::info("Creating #{ first_date == second_date ? 'entry' : 'entries' }: #{ date_string }")
125
-
126
- # Download Sifttter files from Dropbox.
127
- dbu = DropboxUploader.new(Configuration::db_uploader[:exe_filepath])
128
- dbu.verbose = SifttterRedux.verbose
129
- dbu.local_target = Configuration::sifttter_redux[:sifttter_local_filepath]
130
- dbu.remote_target = Configuration::sifttter_redux[:sifttter_remote_filepath]
131
- dbu.message = 'Downloading Sifttter files...'
132
-
133
- CLIMessage::info_block(dbu.message || dbu::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
134
- dbu.download
135
- end
129
+ dates = SifttterRedux::get_dates_from_options(options)
130
+ unless dates.nil?
131
+ first_date = dates.first
132
+ second_date = dates.reverse_each.first
136
133
 
137
- # Process a new Sifttter entry for each date.
138
- dates.each do |date|
139
- Sifttter::run(date)
140
- end
134
+ date_string = first_date.strftime('%B %d, %Y')
135
+ date_string << " to #{ second_date.strftime('%B %d, %Y') }" if first_date != second_date
136
+ messenger.info("Creating #{ first_date == second_date ? 'entry' : 'entries' }: #{ date_string }")
141
137
 
142
- # Upload any Day One entries to Dropbox (if there are any).
143
- unless Dir[Configuration::sifttter_redux[:dayone_local_filepath] + '/*'].empty?
144
- dbu.local_target = "#{ Configuration::sifttter_redux[:dayone_local_filepath] }/*"
145
- dbu.remote_target = Configuration::sifttter_redux[:dayone_remote_filepath]
146
- dbu.message = 'Uploading Day One entries to Dropbox...'
138
+ # Download Sifttter files from Dropbox.
139
+ dbu = SifttterRedux::DropboxUploader.new(configuration.db_uploader[:exe_filepath])
140
+ dbu.verbose = SifttterRedux.verbose
141
+ dbu.local_target = configuration.sifttter_redux[:sifttter_local_filepath]
142
+ dbu.remote_target = configuration.sifttter_redux[:sifttter_remote_filepath]
143
+ dbu.message = 'Downloading Sifttter files...'
147
144
 
148
- CLIMessage::info_block(dbu.message || dbu::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
149
- dbu.upload
150
- end
151
- end
145
+ messenger.info_block(dbu.message || dbu::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
146
+ dbu.download
147
+ end
152
148
 
153
- # Remove any downloaded local files that we no longer need.
154
- SifttterRedux::cleanup_temp_files
149
+ # Process a new Sifttter entry for each date.
150
+ dates.each do |date|
151
+ SifttterRedux::Sifttter.run(date)
155
152
  end
156
- rescue StandardError => e
157
- CLIMessage::error(e.to_s)
158
- exit!(1)
153
+
154
+ # Upload any Day One entries to Dropbox (if there are any).
155
+ unless Dir[configuration.sifttter_redux[:dayone_local_filepath] + '/*'].empty?
156
+ dbu.local_target = "#{ configuration.sifttter_redux[:dayone_local_filepath] }/*"
157
+ dbu.remote_target = configuration.sifttter_redux[:dayone_remote_filepath]
158
+ dbu.message = 'Uploading Day One entries to Dropbox...'
159
+
160
+ messenger.info_block(dbu.message || SifttterRedux::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
161
+ dbu.upload
162
+ end
163
+ end
164
+
165
+ # Remove any downloaded local files that we no longer need.
166
+ SifttterRedux.cleanup_temp_files
159
167
  end
160
168
  end
161
169
 
@@ -164,22 +172,25 @@ end
164
172
  # ------------------------------------------------------
165
173
  # init command
166
174
  #
167
- # Initializes the script.
175
+ # Initializes the app by asking the user for information
176
+ # needed torun.
168
177
  # ------------------------------------------------------
169
- desc 'Install and SifttterRedux::initialize dependencies'
178
+ desc 'Install and initialize dependencies'
170
179
  command :init do |c|
171
180
  c.switch([:s], desc: 'Run init from scratch (i.e., clear out all values from configuration)')
172
-
173
181
  c.action do |global_options, options, args|
174
- CLIMessage::section_block('INITIALIZING...') do
182
+ messenger.section_block('INITIALIZING...') do
175
183
  if options[:s]
176
184
  SifttterRedux::init(true)
177
185
  else
178
186
  long_message = "You've already initialized Sifttter Redux. Do it again?"
179
- SifttterRedux::init if CLIMessage::prompt(long_message, 'N').downcase == 'y'
187
+ SifttterRedux::init if messenger.prompt(long_message, 'N').downcase == 'y'
180
188
  end
181
189
  end
182
190
  end
183
191
  end
184
192
 
193
+ # ======================================================
194
+ # Run!
195
+ # ======================================================
185
196
  exit run(ARGV)
@@ -0,0 +1,7 @@
1
+ Feature: UI
2
+ As a user, when I ask for help, I should be presented
3
+ with instructions on how to run the app.
4
+
5
+ Scenario: Display help instructions
6
+ When I get help for "srd"
7
+ Then the exit status should be 0
@@ -0,0 +1,130 @@
1
+ @announce
2
+ Feature: Initialization
3
+ As a user, when I initialize Sifttter Redux,
4
+ I should be guided through the process as
5
+ necessary.
6
+
7
+ Scenario: Basic Initialization
8
+ Given no file located at "/tmp/srd/.sifttter_redux"
9
+ And an empty file located at "/tmp/srd/.dropbox_uploader"
10
+ When I run `srd init` interactively
11
+ And I type ""
12
+ And I type "~/sifttter_download"
13
+ And I type "/Apps/ifttt/Sifttter"
14
+ And I type "~/day_one_download"
15
+ And I type "/Apps/Day\ One/Journal.dayone/entries"
16
+ Then the exit status should be 0
17
+ And the file "/tmp/srd/.sifttter_redux" should contain:
18
+ """
19
+ ---
20
+ :sifttter_redux:
21
+ :config_location: "/tmp/srd/.sifttter_redux"
22
+ :log_level: WARN
23
+ """
24
+ And the file "/tmp/srd/.sifttter_redux" should contain:
25
+ """
26
+ :sifttter_local_filepath: "/tmp/srd/sifttter_download"
27
+ :sifttter_remote_filepath: "/Apps/ifttt/Sifttter"
28
+ :dayone_local_filepath: "/tmp/srd/day_one_download"
29
+ :dayone_remote_filepath: "/Apps/Day\\ One/Journal.dayone/entries"
30
+ :db_uploader:
31
+ :base_filepath: "/usr/local/opt"
32
+ :dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
33
+ :exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
34
+ """
35
+
36
+ Scenario: Reinitialization (refuse)
37
+ Given a file located at "/tmp/srd/.sifttter_redux" with the contents:
38
+ """
39
+ ---
40
+ :sifttter_redux:
41
+ :config_location: "/tmp/srd/.sifttter_redux"
42
+ :log_level: WARN
43
+ :version: 0.5.4
44
+ :sifttter_local_filepath: "/tmp/srd/sifttter_download"
45
+ :sifttter_remote_filepath: "/Apps/ifttt/Sifttter"
46
+ :dayone_local_filepath: "/tmp/srd/day_one_download"
47
+ :dayone_remote_filepath: "/Apps/Day\\ One/Journal.dayone/entries"
48
+ :db_uploader:
49
+ :base_filepath: "/usr/local/opt"
50
+ :dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
51
+ :exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
52
+ """
53
+ And an empty file located at "/tmp/srd/.dropbox_uploader"
54
+ When I run `srd init` interactively
55
+ And I type ""
56
+ Then the exit status should be 0
57
+
58
+ Scenario: Reinitialization (accept)
59
+ Given a file located at "/tmp/srd/.sifttter_redux" with the contents:
60
+ """
61
+ ---
62
+ :sifttter_redux:
63
+ :config_location: "/tmp/srd/.sifttter_redux"
64
+ :log_level: WARN
65
+ :version: 0.5.4
66
+ :sifttter_local_filepath: "/tmp/srd/sifttter_download"
67
+ :sifttter_remote_filepath: "/Apps/ifttt/Sifttter"
68
+ :dayone_local_filepath: "/tmp/srd/day_one_download"
69
+ :dayone_remote_filepath: "/Apps/Day\\ One/Journal.dayone/entries"
70
+ :db_uploader:
71
+ :base_filepath: "/usr/local/opt"
72
+ :dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
73
+ :exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
74
+ """
75
+ And an empty file located at "/tmp/srd/.dropbox_uploader"
76
+ When I run `srd init` interactively
77
+ And I type "y"
78
+ And I type ""
79
+ And I type "~/sifttter_download2"
80
+ And I type "/Apps/ifttt/Sifttter2"
81
+ And I type "~/day_one_download2"
82
+ And I type "/Apps/Day\ One/Journal.dayone/entries2"
83
+ Then the exit status should be 0
84
+ And the file "/tmp/srd/.sifttter_redux" should contain:
85
+ """
86
+ ---
87
+ :sifttter_redux:
88
+ :config_location: "/tmp/srd/.sifttter_redux"
89
+ :log_level: WARN
90
+ """
91
+ And the file "/tmp/srd/.sifttter_redux" should contain:
92
+ """
93
+ :sifttter_local_filepath: "/tmp/srd/sifttter_download2"
94
+ :sifttter_remote_filepath: "/Apps/ifttt/Sifttter2"
95
+ :dayone_local_filepath: "/tmp/srd/day_one_download2"
96
+ :dayone_remote_filepath: "/Apps/Day\\ One/Journal.dayone/entries2"
97
+ :db_uploader:
98
+ :base_filepath: "/usr/local/opt"
99
+ :dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
100
+ :exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
101
+ """
102
+
103
+ Scenario: Reinitialization (from scratch)
104
+ Given no file located at "/tmp/srd/.sifttter_redux"
105
+ And an empty file located at "/tmp/srd/.dropbox_uploader"
106
+ When I run `srd init -s` interactively
107
+ And I type ""
108
+ And I type "~/sifttter_download"
109
+ And I type "/Apps/ifttt/Sifttter"
110
+ And I type "~/day_one_download"
111
+ And I type "/Apps/Day\ One/Journal.dayone/entries"
112
+ Then the exit status should be 0
113
+ And the file "/tmp/srd/.sifttter_redux" should contain:
114
+ """
115
+ ---
116
+ :sifttter_redux:
117
+ :config_location: "/tmp/srd/.sifttter_redux"
118
+ :log_level: WARN
119
+ """
120
+ And the file "/tmp/srd/.sifttter_redux" should contain:
121
+ """
122
+ :sifttter_local_filepath: "/tmp/srd/sifttter_download"
123
+ :sifttter_remote_filepath: "/Apps/ifttt/Sifttter"
124
+ :dayone_local_filepath: "/tmp/srd/day_one_download"
125
+ :dayone_remote_filepath: "/Apps/Day\\ One/Journal.dayone/entries"
126
+ :db_uploader:
127
+ :base_filepath: "/usr/local/opt"
128
+ :dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
129
+ :exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
130
+ """