sifttter-redux 0.6.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f91e99b36d3cad97575616fb109ec3d2fa8ba5eb
4
- data.tar.gz: a580c1e1fb3c78b69fcec0e26bbfb39b06b65c22
3
+ metadata.gz: 090949c07d19d271f5967f3ef4a39499e481ecae
4
+ data.tar.gz: dc87641ba282c42ac14a945ccf178f2707dde6ff
5
5
  SHA512:
6
- metadata.gz: 092a22e0178972b943b6f87273caa8370f9abebfb57333c60858303f5cdb1037024549003f046af03ff6d849754cac68e92d42d39424e914bf5c7490c8d4a477
7
- data.tar.gz: e002acd2182c37bba56b5909a5091f3248582dec33ecaae257de376bb36e910a4346fe8f15103ba03120e114a8d3c8a21c70b11392b8affb5c045c42c0e2496e
6
+ metadata.gz: 70ca3cfbbce6a86e794bac9d114aa67c613505cc1c619788a6e99baadd5bdd597e92ab65bdebda3ac4a3fb34df59df48dea3b347eba45b59e84f3372f4aebbee
7
+ data.tar.gz: 514072d0313a62eb283dec3c34eb6a5f612ea722162d2a220e69a9b1c994c8f9f3a1a4c36994980073b0617092b7bf9b5aef6ced4a53359acc882e9aaed2dc44
data/HISTORY.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 1.0.0 (2014-04-21)
2
+
3
+ * Added new Sifttter file format (which allows for any Markdown)
4
+ * Added `srd upgrade` to upgrade to new format
5
+ * Lots of bugfixes
6
+
1
7
  # 0.6.4 (2014-04-13)
2
8
 
3
9
  * Now using Configurator's `compare_version`
@@ -169,4 +175,4 @@
169
175
 
170
176
  # 0.1.0
171
177
 
172
- * Initial release of Sifttter Redux
178
+ * Initial release of Sifttter Redux
data/README.md CHANGED
@@ -3,7 +3,32 @@ Sifttter Redux
3
3
  [![Build Status](https://travis-ci.org/bachya/Sifttter-Redux.svg?branch=master)](https://travis-ci.org/bachya/Sifttter-Redux)
4
4
  [![Gem Version](https://badge.fury.io/rb/sifttter-redux.svg)](http://badge.fury.io/rb/sifttter-redux)
5
5
 
6
- Siftter Redux is a modification of Craig Eley's [Sifttter](http://craigeley.com/post/72565974459/sifttter-an-ifttt-to-day-one-logger "Sifttter"), a script to collect information from [IFTTT](http://www.ifttt.com "IFTTT") and place it in a [Day One](http://dayoneapp.com, "Day One") journal.
6
+ # Upgrading From 0.x.x to 1.0.0?
7
+
8
+ Version 1.0.0 uses a new schema that allows for any type of Markdown. Using
9
+ version 1.0.0, Sifttter files need to follow this format:
10
+
11
+ ```
12
+ @begin
13
+ @date April 21, 2014
14
+ **Any** sort of *Markdown* goes here...
15
+ @end
16
+ ```
17
+
18
+ Note that a new command has been introduced that attempts to upgrade to this
19
+ new format. **Although the command backs up your current Sifttter files, you
20
+ are strongly encouraged to make a separate, manual backup.**
21
+
22
+ ```Bash
23
+ $ srd upgrade
24
+ ```
25
+
26
+ # Intro
27
+
28
+ Siftter Redux is a modification of Craig Eley's
29
+ [Sifttter](http://craigeley.com/post/72565974459/sifttter-an-ifttt-to-day-one-logger "Sifttter"),
30
+ a script to collect information from [IFTTT](http://www.ifttt.com "IFTTT") and
31
+ place it in a [Day One](http://dayoneapp.com, "Day One") journal.
7
32
 
8
33
  Siftter Redux has several fundamental differences:
9
34
 
@@ -14,7 +39,8 @@ Siftter Redux has several fundamental differences:
14
39
 
15
40
  # Prerequisites
16
41
 
17
- In addition to Git (which, given you being on this site, I'll assume you have), Ruby (v. 1.9.3 or greater) is needed.
42
+ In addition to Git (which, given you being on this site, I'll assume you have),
43
+ Ruby (v. 1.9.3 or greater) is needed.
18
44
 
19
45
  # Installation
20
46
 
@@ -52,7 +78,8 @@ COMMANDS
52
78
  init - Install and initialize dependencies
53
79
  ```
54
80
 
55
- Note that each command's options can be revealed by adding the `--help` switch after the command. For example:
81
+ Note that each command's options can be revealed by adding the `--help` switch
82
+ after the command. For example:
56
83
 
57
84
  ```
58
85
  $ srd exec --help
@@ -81,7 +108,7 @@ $ srd init
81
108
 
82
109
  Initialization will perform the following steps:
83
110
 
84
- 1. Download [Dropbox Uploader](https://github.com/andreafabrizi/Dropbox-Uploader "Dropbox-Uploder") to a location of your choice.
111
+ 1. Download [Dropbox Uploader](https://github.com/andreafabrizi/Dropbox-Uploader "Dropbox-Uploder")to a location of your choice.
85
112
  2. Automatically configure Dropbox Uploader.
86
113
  3. Collect some user paths (note that you can use tab completion here!):
87
114
  * The location on your filesystem where Sifttter files will be temporarily stored
@@ -91,11 +118,13 @@ Initialization will perform the following steps:
91
118
 
92
119
  ## Pathing
93
120
 
94
- Note that when Sifttter Redux asks you for paths, it will ask for "local" and "remote" filepaths. It's important to understand the difference.
121
+ Note that when Sifttter Redux asks you for paths, it will ask for "local" and
122
+ "remote" filepaths. It's important to understand the difference.
95
123
 
96
124
  ### Local Filepaths
97
125
 
98
- Local filepaths are, as you'd expect, filepaths on your local machine. Some examples might be:
126
+ Local filepaths are, as you'd expect, filepaths on your local machine. Some
127
+ examples might be:
99
128
 
100
129
  * `/tmp/my_data`
101
130
  * `/home/bob/ifttt/sifttter_data`
@@ -103,7 +132,10 @@ Local filepaths are, as you'd expect, filepaths on your local machine. Some exam
103
132
 
104
133
  ### Remote Filepaths
105
134
 
106
- Remote filepaths, on the other hand, are absolute filepaths in your Dropbox folder (*as Dropbox Uploader would see them*). For instance, `/home/bob/Dropbox/apps/sifttter` is *not* a valid remote filepath; rather, `/apps/sifttter` would be correct.
135
+ Remote filepaths, on the other hand, are absolute filepaths in your Dropbox
136
+ folder (*as Dropbox Uploader would see them*). For instance,
137
+ `/home/bob/Dropbox/apps/sifttter` is *not* a valid remote filepath; rather,
138
+ `/apps/sifttter` would be correct.
107
139
 
108
140
  ## Basic Execution
109
141
 
@@ -121,9 +153,12 @@ $ srd exec
121
153
 
122
154
  ## "Catch-up" Mode
123
155
 
124
- Sometimes, events occur that prevent Sifttter Redux from running (power loss to your device, a bad Cron job, etc.). In this case, Sifttter Redux's "catch-up" mode can be used to collect any valid journal on or before today's date.
156
+ Sometimes, events occur that prevent Sifttter Redux from running (power loss to
157
+ your device, a bad Cron job, etc.). In this case, Sifttter Redux's "catch-up"
158
+ mode can be used to collect any valid journal on or before today's date.
125
159
 
126
- There are many ways to use this mode (note that "today" in these examples is **February 15, 2014**):
160
+ There are many ways to use this mode (note that "today" in these examples is
161
+ **February 15, 2014**):
127
162
 
128
163
  ### Yesterday Catch-up
129
164
 
@@ -143,7 +178,8 @@ $ srd exec -y
143
178
 
144
179
  ### Last "N" Days Catch-up
145
180
 
146
- Sifttter Redux allows you to specify the number of days back it should look for new entries:
181
+ Sifttter Redux allows you to specify the number of days back it should look for
182
+ new entries:
147
183
 
148
184
  ```
149
185
  $ srd exec -n 3
@@ -180,7 +216,9 @@ $ srd exec -n 12
180
216
  #### EXECUTION COMPLETE!
181
217
  ```
182
218
 
183
- Note that this option goes until yesterday ("yesterday" because you might not be ready to have today's entries scanned). If you'd rather include today's date, you can always add the `-i` switch:
219
+ Note that this option goes until yesterday ("yesterday" because you might not be
220
+ ready to have today's entries scanned). If you'd rather include today's date, you
221
+ can always add the `-i` switch:
184
222
 
185
223
  ```
186
224
  $ srd exec -i -n 3
@@ -199,7 +237,8 @@ $ srd exec -i -n 3
199
237
 
200
238
  ### Last "N" Weeks Catch-up
201
239
 
202
- Sifttter Redux also allows you to specify a number of weeks back that should be scanned for new entries:
240
+ Sifttter Redux also allows you to specify a number of weeks back that should be
241
+ scanned for new entries:
203
242
 
204
243
  ```
205
244
  $ srd exec -w 1
@@ -312,7 +351,8 @@ $ srd exec -f 2014-02-01 -t 2014-02-12
312
351
  #### EXECUTION COMPLETE!
313
352
  ```
314
353
 
315
- Even more simply, to create entries from a specific point until yesterday ("yesterday" because you might not be ready to have today's entries scanned):
354
+ Even more simply, to create entries from a specific point until yesterday
355
+ ("yesterday" because you might not be ready to have today's entries scanned):
316
356
 
317
357
  ```
318
358
  $ srd exec -f 2014-02-01
@@ -367,7 +407,7 @@ $ srd exec -i -f 2014-02-01
367
407
 
368
408
  Two notes to be aware of:
369
409
 
370
- * `-f` and `-t` are *inclusive* parameters, meaning that when specified, those dates will be included when searching for Siftter data.
410
+ * `-f` and `-t` are *inclusive* parameters, meaning that when specified, thosedates will be included when searching for Siftter data.
371
411
  * Although you can specify `-f` by itself, you cannot specify `-t` by itself.
372
412
 
373
413
  Sifttter Redux makes use of the excellent [Chronic gem](https://github.com/mojombo/chronic "Chronic"), which provides natural language parsing for dates and times. This means that you can run commands with more "human" dates:
@@ -392,9 +432,13 @@ See [Chronic's Examples section](https://github.com/mojombo/chronic#examples "Ch
392
432
 
393
433
  # Cron Job
394
434
 
395
- By installing an entry to a `crontab`, Sifttter Redux can be run automatically on a schedule. The aim of this project was to use a Raspberry Pi; as such, the instructions below are specifically catered to that platform. That said, it should be possible to install and configure on any *NIX platform.
435
+ By installing an entry to a `crontab`, Sifttter Redux can be run automatically
436
+ on a schedule. The aim of this project was to use a Raspberry Pi; as such, the
437
+ instructions below are specifically catered to that platform. That said, it
438
+ should be possible to install and configure on any *NIX platform.
396
439
 
397
- One issue that arises is the loading of the bundled gems; because cron runs in a limited environment, it does not automatically know where to find installed gems.
440
+ One issue that arises is the loading of the bundled gems; because cron runs in a
441
+ limited environment, it does not automatically know where to find installed gems.
398
442
 
399
443
  ## Using RVM
400
444
 
@@ -414,7 +458,8 @@ $ bundle install --global
414
458
 
415
459
  # Logging
416
460
 
417
- Sifttter Redux logs a lot of good info to `~/.sifttter_redux_log`. It makes use of Ruby's standard log levels:
461
+ Sifttter Redux logs a lot of good info to `~/.sifttter_redux_log`. It makes use
462
+ of Ruby's standard log levels:
418
463
 
419
464
  * DEBUG
420
465
  * INFO
@@ -423,15 +468,15 @@ Sifttter Redux logs a lot of good info to `~/.sifttter_redux_log`. It makes use
423
468
  * FATAL
424
469
  * UNKNOWN
425
470
 
426
- If you want to see more or less in your log files, simply change the `log_level` value in `~/.sifttter_redux` to your desired level.
427
-
428
- # Known Issues & Future Releases
429
-
430
- Bugs, issues, and enhancement requests (my own or those submitted by others) can be found on the [Issues Page](https://github.com/bachya/Sifttter-Redux/issues "Open Items").
471
+ If you want to see more or less in your log files, simply change the `log_level`
472
+ value in `~/.sifttter_redux` to your desired level.
431
473
 
432
474
  # Bugs and Feature Requests
433
475
 
434
- To report bugs with or suggest features/changes for Sifttter Redux, please use the [Issues Page](http://github.com/bachya/sifttter-redux/issues).
476
+ My current roadmap can be found on my [Trello board](https://trello.com/b/z4vl3YxC/sifttter-redux "Sifttter Redux Trello Board")
477
+
478
+ To report bugs with or suggest features/changes for Sifttter Redux, please use
479
+ the [Issues Page](http://github.com/bachya/sifttter-redux/issues).
435
480
 
436
481
  Contributions are welcome and encouraged. To contribute:
437
482
 
@@ -447,15 +492,26 @@ Contributions are welcome and encouraged. To contribute:
447
492
 
448
493
  Copyright © 2014 Aaron Bach <bachya1208@gmail.com>
449
494
 
450
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
495
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
496
+ this software and associated documentation files (the 'Software'), to deal in the
497
+ Software without restriction, including without limitation the rights to use,
498
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
499
+ Software, and to permit persons to whom the Software is furnished to do so,
500
+ subject to the following conditions:
451
501
 
452
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
502
+ The above copyright notice and this permission notice shall be included in all
503
+ copies or substantial portions of the Software.
453
504
 
454
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
505
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
506
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
507
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
508
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
509
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
510
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
455
511
 
456
512
  # Credits
457
513
 
458
514
  * Craig Eley for [Sifttter](http://craigeley.com/post/72565974459/sifttter-an-ifttt-to-day-one-logger "Sifttter") and for giving me the idea for Sifttter Redux
459
515
  * Dave Copeland for [GLI](https://github.com/davetron5000/gli "GLI")
460
516
  * Andrea Fabrizi for [Dropbox Uploader](https://github.com/andreafabrizi/Dropbox-Uploader "Dropbox Uploader")
461
- * ~~Tom Preston-Werner~~ (sorry: can't support [harrassment](http://www.businessinsider.com/github-co-founder-suspended-2014-3 "GitHub Founder Tom Preston-Werner Suspended After Harassment Allegations")) ~~and~~ Lee Jarvis for [Chronic](https://github.com/mojombo/chronic "Chronic")
517
+ * ~~Tom Preston-Werner~~ (sorry: can't support [harrassment](http://www.businessinsider.com/github-co-founder-suspended-2014-3 "GitHub Founder Tom Preston-Werner Suspended After Harassment Allegations")) ~~and~~ Lee Jarvis for [Chronic](https://github.com/mojombo/chronic "Chronic")
data/bin/srd CHANGED
@@ -32,6 +32,7 @@
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 'archive/zip'
35
36
  require 'cliutils'
36
37
  require 'gli'
37
38
  require 'sifttter-redux'
@@ -44,13 +45,8 @@ include GLI::App
44
45
  # ======================================================
45
46
  # App Info
46
47
  # ======================================================
47
- program_desc 'Sifttter Redux
48
-
49
- A customized IFTTT-to-Day One service that allows for
50
- smart installation and automated running on a standalone
51
- *NIX device (such as a Raspberry Pi).'
52
-
53
- version SifttterRedux::VERSION
48
+ program_desc(SifttterRedux::DESCRIPTION)
49
+ version(SifttterRedux::VERSION)
54
50
 
55
51
  # ======================================================
56
52
  # Global Flags and Switches
@@ -61,7 +57,6 @@ switch([:verbose], desc: 'Turns on verbose output')
61
57
  # Pre, Post, and Error
62
58
  # ======================================================
63
59
  pre do |global, command, options, args|
64
-
65
60
  # Load SifttterRedux configuration module.
66
61
  load_configuration(SifttterRedux::DEFAULT_SRD_CONFIG_FILEPATH)
67
62
  file_logger = Logger.new(SifttterRedux::DEFAULT_SRD_LOG_FILEPATH)
@@ -84,7 +79,6 @@ pre do |global, command, options, args|
84
79
  SifttterRedux.init(true)
85
80
  exit!(0)
86
81
  end
87
-
88
82
  true
89
83
  end
90
84
 
@@ -176,14 +170,65 @@ desc 'Install and initialize dependencies'
176
170
  command :init do |c|
177
171
  c.switch([:s], desc: 'Run init from scratch (i.e., clear out all values from configuration)')
178
172
  c.action do |global_options, options, args|
179
- messenger.section_block('INITIALIZING...') do
180
- if options[:s]
181
- SifttterRedux::init(true)
182
- else
183
- long_message = "You've already initialized Sifttter Redux. Do it again?"
184
- SifttterRedux::init if messenger.prompt(long_message, 'N').downcase == 'y'
185
- end
173
+ if options[:s]
174
+ SifttterRedux::init(true)
175
+ else
176
+ long_message = "You've already initialized Sifttter Redux. Do it again?"
177
+ SifttterRedux::init if messenger.prompt(long_message, 'N').downcase == 'y'
178
+ end
179
+ end
180
+ end
181
+
182
+ # ------------------------------------------------------
183
+ # upgrade command
184
+ #
185
+ # Upgrades existing Sifttter files to the format needed
186
+ # by v 1.x.x.
187
+ # ------------------------------------------------------
188
+ desc 'Upgrades Sifttter files to the new format'
189
+ command :upgrade do |c|
190
+ c.switch([:verbose], desc: 'Turns on verbose output')
191
+ c.action do |global_options, options, args|
192
+ SifttterRedux.verbose = global_options[:verbose] || options[:verbose]
193
+
194
+ # Set the archive filepath and the files that will go into it.
195
+ filename = "#{ ENV['HOME'] }/sifttter_backup_#{ Time.now.to_i }.zip"
196
+
197
+ # Download Sifttter files from Dropbox.
198
+ dbu = SifttterRedux::DropboxUploader.new(configuration.db_uploader[:exe_filepath])
199
+ dbu.verbose = SifttterRedux.verbose
200
+ dbu.local_target = configuration.sifttter_redux[:sifttter_local_filepath]
201
+ dbu.remote_target = configuration.sifttter_redux[:sifttter_remote_filepath]
202
+ dbu.message = "Backing up Sifttter files to #{ filename }..."
203
+
204
+ messenger.info_block(dbu.message || dbu::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
205
+ dbu.download
186
206
  end
207
+
208
+ # Archive the Sifttter files.
209
+ Archive::Zip.archive(filename, configuration.sifttter_redux[:sifttter_local_filepath])
210
+
211
+ # Replace the old scheme with the new one.
212
+ Dir.glob(configuration.sifttter_redux[:sifttter_local_filepath] + '/*.txt').each do |file|
213
+ t = File.read(file)
214
+ t.gsub!(/^- /, "@begin\n@date ")
215
+ t.gsub!(/ - /, "\n- ")
216
+ t.gsub!(/\s?@done/, '@end')
217
+ messenger.debug { "Replacing contents of file: #{ file }"}
218
+ File.open(file, 'w') { |f| f.write(t) }
219
+ end
220
+
221
+ # Upload the new Sifttter files back to Dropbox.
222
+ dbu.local_target = "#{ configuration.sifttter_redux[:sifttter_local_filepath] }"
223
+ dbu.remote_target = Pathname.new(configuration.sifttter_redux[:sifttter_remote_filepath]).dirname.to_s
224
+ dbu.message = "Uploading revised Sifttter files to Dropbox..."
225
+
226
+ messenger.info_block(dbu.message || dbu::DEFAULT_MESSAGE, 'Done.', SifttterRedux.verbose) do
227
+ dbu.upload
228
+ end
229
+
230
+ # Remove any downloaded local files that we no longer need.
231
+ SifttterRedux.cleanup_temp_files
187
232
  end
188
233
  end
189
234
 
@@ -53,7 +53,7 @@ Feature: Initialization
53
53
  When I run `srd init` interactively
54
54
  And I type ""
55
55
  Then the exit status should be 0
56
-
56
+
57
57
  Scenario: Reinitialization (accept)
58
58
  Given a file located at "/tmp/srd/.sifttter_redux" with the contents:
59
59
  """
@@ -97,8 +97,8 @@ Feature: Initialization
97
97
  base_filepath: "/usr/local/opt"
98
98
  dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
99
99
  exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
100
- """
101
-
100
+ """
101
+
102
102
  Scenario: Reinitialization (from scratch)
103
103
  Given no file located at "/tmp/srd/.sifttter_redux"
104
104
  And an empty file located at "/tmp/srd/.dropbox_uploader"
@@ -126,4 +126,4 @@ Feature: Initialization
126
126
  base_filepath: "/usr/local/opt"
127
127
  dbu_filepath: "/usr/local/opt/Dropbox-Uploader"
128
128
  exe_filepath: "/usr/local/opt/Dropbox-Uploader/dropbox_uploader.sh"
129
- """
129
+ """
@@ -18,7 +18,7 @@ module SifttterRedux
18
18
  DESCRIPTION = 'A customized IFTTT-to-Day One service that allows for smart installation and automated running on a standalone *NIX device (such as a Raspberry Pi).'
19
19
 
20
20
  # The last version to require a config update
21
- NEWEST_CONFIG_VERSION = '0.6'
21
+ NEWEST_CONFIG_VERSION = '1.0.0'
22
22
 
23
23
  # Hash of preference files
24
24
  PREF_FILES = {
@@ -29,5 +29,5 @@ module SifttterRedux
29
29
  SUMMARY = 'Automated IFTTT to Day One engine.'
30
30
 
31
31
  # The Gem's version
32
- VERSION = '0.6.4'
33
- end
32
+ VERSION = '1.0.0'
33
+ end
@@ -1,42 +1,79 @@
1
1
  module SifttterRedux
2
2
  # Sifttter Module
3
- # Wrapper module for Sifttter itself
3
+ # Used to examine Sifttter data and create
4
+ # Day One entries as necessary.
4
5
  module Sifttter
5
- # Sifttter: An IFTTT-to-Day One Logger by Craig Eley
6
- # Based on tp-dailylog.rb by Brett Terpstra 2012
7
- # @param [Date] date The date to use when scanning Sifttter
8
- # @return [void]
9
- def self.run(date)
10
- uuid = SecureRandom.uuid.upcase.gsub(/-/, '').strip
6
+ extend self
11
7
 
12
- date_for_title = date.strftime('%B %d, %Y')
13
- datestamp = date.to_time.utc.iso8601
14
- starred = false
8
+ class << self
9
+ # Stores the collection of entries to create.
10
+ # @return [Hash]
11
+ attr_accessor :entries
12
+ end
15
13
 
16
- template = ERB.new <<-XMLTEMPLATE
14
+ # Generates an ERB template for a Day One entry
15
+ # @param [String] datestamp The ISO8601 datestamp
16
+ # @param [String] entrytext The text of the entry
17
+ # @param [Boolean] starred Whether the entry should be starred
18
+ # @param [String] uuid The UUID of the entry
19
+ def generate_template(datestamp, entrytext, starred, uuid)
20
+ ERB.new <<-XMLTEMPLATE
17
21
  <?xml version="1.0" encoding="UTF-8"?>
18
22
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
19
23
  <plist version="1.0">
20
24
  <dict>
21
- <key>Creation Date</key>
22
- <date><%= datestamp %></date>
23
- <key>Entry Text</key>
24
- <string><%= entrytext %></string>
25
- <key>Starred</key>
26
- <<%= starred %>/>
27
- <key>Tags</key>
28
- <array>
29
- <string>daily logs</string>
30
- </array>
31
- <key>UUID</key>
32
- <string><%= uuid %></string>
25
+ <key>Creation Date</key>
26
+ <date><%= datestamp %></date>
27
+ <key>Entry Text</key>
28
+ <string><%= entrytext %></string>
29
+ <key>Starred</key>
30
+ <<%= starred %>/>
31
+ <key>Tags</key>
32
+ <array>
33
+ <string>daily logs</string>
34
+ </array>
35
+ <key>UUID</key>
36
+ <string><%= uuid %></string>
33
37
  </dict>
34
38
  </plist>
35
39
  XMLTEMPLATE
40
+ end
41
+
42
+ # Opens a filepath and parses it for Sifttter
43
+ # data for the passed date.
44
+ # @param [String] file The filepath to parse
45
+ # @param [Date] date The date to search for
46
+ # @return [void]
47
+ def parse_sifttter_file(filepath, date)
48
+ title = File.basename(filepath).gsub(/^.*?\/([^\/]+)$/, "\\1") + "\n"
36
49
 
37
50
  date_regex = "(?:#{ date.strftime("%B") } 0?#{ date.strftime("%-d") }, #{ date.strftime("%Y") })"
38
51
  time_regex = "(?:\d{1,2}:\d{1,2}\s?[AaPpMm]{2})"
52
+ entry_regex = /@begin\n@date\s#{ date_regex }(?: at (.*?)\n)?(.*?)@end/m
53
+
54
+ contents = File.read(filepath)
55
+ cur_entries = contents.scan(entry_regex)
56
+ unless cur_entries.empty?
57
+ @entries.merge!(title => []) unless @entries.key?(title)
58
+ cur_entries.each { |e| @entries[title] << [e[0], e[1].strip] }
59
+ end
60
+ end
39
61
 
62
+ # Finds Siftter data for the passed date and
63
+ # creates corresponding Day One entries.
64
+ # @param [Date] date The date to search for
65
+ # @return [void]
66
+ def self.run(date)
67
+ @entries = {}
68
+ uuid = SecureRandom.uuid.upcase.gsub(/-/, '').strip
69
+ date_for_title = date.strftime('%B %d, %Y')
70
+ datestamp = date.to_time.utc.iso8601
71
+ starred = false
72
+
73
+
74
+ output_dir = configuration.sifttter_redux[:dayone_local_filepath]
75
+ Dir.mkdir(output_dir) unless Dir.exists?(output_dir)
76
+
40
77
  files = `find #{ configuration.sifttter_redux[:sifttter_local_filepath] } -type f -name "*.txt" | grep -v -i daily | sort`
41
78
  if files.empty?
42
79
  messenger.error('No Sifttter files to parse...')
@@ -44,47 +81,29 @@ module SifttterRedux
44
81
  messenger.error("Is #{ configuration.sifttter_redux[:sifttter_remote_filepath] } the correct remote filepath?")
45
82
  exit!(1)
46
83
  end
47
-
48
- projects = []
84
+
49
85
  files.split("\n").each do |file|
50
- if File.exists?(file.strip)
51
- f = File.open(file.strip, encoding: 'UTF-8')
52
- lines = f.read
53
- f.close
54
- project = '### ' + File.basename(file).gsub(/^.*?\/([^\/]+)$/, "\\1") + "\n"
55
-
56
- found_completed = false
57
- lines.each_line do |line|
58
- if line =~ /&/
59
- line.gsub!(/[&]/, 'and')
60
- end
61
- if line =~ /#{ date_regex }/
62
- found_completed = true
63
- project += line.gsub(/@done/,"").gsub(/#{ date_regex }\s(-|at)\s/, "").gsub(/#{ time_regex }\s-\s/, "").strip + "\n"
64
- end
65
- end
66
- end
67
- if found_completed
68
- projects.push(project)
69
- end
70
- end
71
-
72
- if projects.length <=0
73
- messenger.warn('No entries found...')
86
+ file.strip!
87
+ if File.exists?(file)
88
+ parse_sifttter_file(file, date)
89
+ end
74
90
  end
91
+
92
+ if @entries.length > 0
93
+ entrytext = "# Things done on #{ date_for_title }\n"
94
+ @entries.each do |key, value|
95
+ entrytext += '### ' + key.gsub(/.txt/, '') + "\n\n"
96
+ value.each { |v| entrytext += "#{ v[1] }\n" }
97
+ entrytext += "\n"
98
+ end
75
99
 
76
- if projects.length > 0
77
- entrytext = "# Things done on #{ date_for_title }\n\n"
78
- projects.each do |project|
79
- entrytext += project.gsub(/.txt/, ' ') + "\n\n"
80
- end
81
-
82
- Dir.mkdir(configuration.sifttter_redux[:dayone_local_filepath]) if !Dir.exists?(configuration.sifttter_redux[:dayone_local_filepath])
83
-
84
- fh = File.new(File.expand_path(configuration.sifttter_redux[:dayone_local_filepath] + '/' + uuid + '.doentry'), 'w+')
85
- fh.puts template.result(binding)
86
- fh.close
87
- messenger.success("Entry logged for #{ date_for_title }...")
100
+ template = generate_template(datestamp, entrytext, starred, uuid)
101
+ fh = File.new(File.expand_path("#{ output_dir }/#{ uuid }.doentry"), 'w+')
102
+ fh.puts template.result(binding)
103
+ fh.close
104
+ messenger.success("Entry logged for #{ date_for_title }...")
105
+ else
106
+ messenger.warn('No entries found...')
88
107
  end
89
108
  end
90
109
  end
@@ -6,17 +6,16 @@ require 'sifttter-redux/sifttter'
6
6
  # The SifttterRedux module, which wraps everything
7
7
  # in this gem.
8
8
  module SifttterRedux
9
-
10
9
  class << self
11
10
  # Stores whether initalization has completed.
12
11
  # @return [Boolean]
13
12
  attr_reader :initialized
14
-
13
+
15
14
  # Stores whether verbose output is turned on.
16
15
  # @return [Boolean]
17
16
  attr_accessor :verbose
18
17
  end
19
-
18
+
20
19
  # Removes temporary directories and their contents
21
20
  # @return [void]
22
21
  def self.cleanup_temp_files
@@ -25,7 +24,7 @@ module SifttterRedux
25
24
  configuration.sifttter_redux[:sifttter_local_filepath]
26
25
  ]
27
26
 
28
- messenger.info_block('Removing temporary local files...') do
27
+ messenger.info_block('Removing temporary local files...') do
29
28
  dirs.each do |d|
30
29
  FileUtils.rm_rf(d)
31
30
  messenger.debug("Removed directory: #{ d }")
@@ -35,52 +34,50 @@ module SifttterRedux
35
34
 
36
35
  # Runs a wizard that installs Dropbox Uploader on the
37
36
  # local filesystem.
38
- # @param [Boolean] from_scratch
37
+ # @param [Boolean] from_scratch
39
38
  # @return [void]
40
39
  def self.dbu_install_wizard(from_scratch = false)
41
40
  valid_path_chosen = false
42
-
43
- messenger.section_block('CONFIGURING DROPBOX UPLOADER...') do
44
- until valid_path_chosen
45
- # Prompt the user for a location to save Dropbox Uploader.
46
- if from_scratch && !configuration.db_uploader[:base_filepath].nil?
47
- default = configuration.db_uploader[:base_filepath]
48
- else
49
- default = DEFAULT_DBU_LOCAL_FILEPATH
50
- end
51
- path = messenger.prompt('Location for Dropbox-Uploader', default)
52
- path = default if path.empty?
53
- path.chop! if path.end_with?('/')
54
-
55
- # If the entered directory exists, clone the repository.
56
- if Dir.exists?(File.expand_path(path))
57
- valid_path_chosen = true
58
-
59
- dbu_path = File.join(path, 'Dropbox-Uploader')
60
- executable_path = File.join(dbu_path, 'dropbox_uploader.sh')
61
-
62
- if File.directory?(dbu_path)
63
- messenger.warn("Using pre-existing Dropbox Uploader at #{ dbu_path }...")
64
- else
65
- messenger.info_block("Downloading Dropbox Uploader to #{ dbu_path }...", 'Done.', true) do
66
- system "git clone https://github.com/andreafabrizi/Dropbox-Uploader.git #{ dbu_path }"
67
- end
68
- end
69
41
 
70
- # If the user has never configured Dropbox Uploader, have them do it here.
71
- unless File.exists?(DEFAULT_DBU_CONFIG_FILEPATH)
72
- messenger.info_block('Initializing Dropbox Uploader...') { system "#{ executable_path }" }
73
- end
42
+ until valid_path_chosen
43
+ # Prompt the user for a location to save Dropbox Uploader.
44
+ if from_scratch && !configuration.db_uploader[:base_filepath].nil?
45
+ default = configuration.db_uploader[:base_filepath]
46
+ else
47
+ default = DEFAULT_DBU_LOCAL_FILEPATH
48
+ end
49
+ path = messenger.prompt('Location for Dropbox-Uploader', default)
50
+ path = default if path.empty?
51
+ path.chop! if path.end_with?('/')
52
+
53
+ # If the entered directory exists, clone the repository.
54
+ if Dir.exists?(File.expand_path(path))
55
+ valid_path_chosen = true
74
56
 
75
- configuration.add_section(:db_uploader) unless configuration.data.key?(:db_uploader)
76
- configuration.db_uploader.merge!({
77
- base_filepath: path,
78
- dbu_filepath: dbu_path,
79
- exe_filepath: executable_path
80
- })
57
+ dbu_path = File.join(path, 'Dropbox-Uploader')
58
+ executable_path = File.join(dbu_path, 'dropbox_uploader.sh')
59
+
60
+ if File.directory?(dbu_path)
61
+ messenger.warn("Using pre-existing Dropbox Uploader at #{ dbu_path }...")
81
62
  else
82
- messenger.error("Sorry, but #{ path } isn't a valid directory.")
63
+ messenger.info_block("Downloading Dropbox Uploader to #{ dbu_path }...", 'Done.', true) do
64
+ system "git clone https://github.com/andreafabrizi/Dropbox-Uploader.git #{ dbu_path }"
65
+ end
83
66
  end
67
+
68
+ # If the user has never configured Dropbox Uploader, have them do it here.
69
+ unless File.exists?(DEFAULT_DBU_CONFIG_FILEPATH)
70
+ messenger.info_block('Initializing Dropbox Uploader...') { system "#{ executable_path }" }
71
+ end
72
+
73
+ configuration.add_section(:db_uploader) unless configuration.data.key?(:db_uploader)
74
+ configuration.db_uploader.merge!({
75
+ base_filepath: path,
76
+ dbu_filepath: dbu_path,
77
+ exe_filepath: executable_path
78
+ })
79
+ else
80
+ messenger.error("Sorry, but #{ path } isn't a valid directory.")
84
81
  end
85
82
  end
86
83
  end
@@ -90,38 +87,36 @@ module SifttterRedux
90
87
  # @param [Hash] options GLI command line options
91
88
  # @return [Range]
92
89
  def self.get_dates_from_options(options)
93
- messenger.section_block('EXECUTING...') do
94
- if options[:c] || options[:n] || options[:w] || options[:y] || options[:f] || options[:t]
95
- # Yesterday
96
- r = DateRangeMaker.yesterday if options[:y]
97
-
98
- # Current Week
99
- r = DateRangeMaker.last_n_weeks(0, options[:i]) if options[:c]
100
-
101
- # Last N Days
102
- r = DateRangeMaker.last_n_days(options[:n].to_i, options[:i]) if options[:n]
103
-
104
- # Last N Weeks
105
- r = DateRangeMaker.last_n_weeks(options[:w].to_i, options[:i]) if options[:w]
106
-
107
- # Custom Range
108
- if (options[:f] || options[:t])
109
- _dates = DateRangeMaker.range(options[:f], options[:t], options[:i])
110
-
111
- if _dates.last > Date.today
112
- messenger.warn("Ignoring overextended end date and using today's date (#{ Date.today })...")
113
- r = (_dates.first..Date.today)
114
- else
115
- r = (_dates.first.._dates.last)
116
- end
90
+ if options[:c] || options[:n] || options[:w] || options[:y] || options[:f] || options[:t]
91
+ # Yesterday
92
+ r = DateRangeMaker.yesterday if options[:y]
93
+
94
+ # Current Week
95
+ r = DateRangeMaker.last_n_weeks(0, options[:i]) if options[:c]
96
+
97
+ # Last N Days
98
+ r = DateRangeMaker.last_n_days(options[:n].to_i, options[:i]) if options[:n]
99
+
100
+ # Last N Weeks
101
+ r = DateRangeMaker.last_n_weeks(options[:w].to_i, options[:i]) if options[:w]
102
+
103
+ # Custom Range
104
+ if (options[:f] || options[:t])
105
+ _dates = DateRangeMaker.range(options[:f], options[:t], options[:i])
106
+
107
+ if _dates.last > Date.today
108
+ messenger.warn("Ignoring overextended end date and using today's date (#{ Date.today })...")
109
+ r = (_dates.first..Date.today)
110
+ else
111
+ r = (_dates.first.._dates.last)
117
112
  end
118
- else
119
- r = DateRangeMaker.today
120
113
  end
121
-
122
- messenger.debug("Date range: #{ r }")
123
- r
114
+ else
115
+ r = DateRangeMaker.today
124
116
  end
117
+
118
+ messenger.debug { "Date range: #{ r }" }
119
+ r
125
120
  end
126
121
 
127
122
  # Initializes Sifttter Redux by downloading and
@@ -147,7 +142,7 @@ module SifttterRedux
147
142
  pm.ask
148
143
  configuration.ingest_prefs(pm)
149
144
 
150
- messenger.debug { "Configuration values after pref collection: #{ configuration.data }" }
145
+ messenger.debug {"Collected configuration values: #{ configuration.data }" }
151
146
  configuration.save
152
147
  @initialized = true
153
148
  end
@@ -156,7 +151,10 @@ module SifttterRedux
156
151
  # re-done and does it.
157
152
  # @return [void]
158
153
  def self.update_config_file
159
- messenger.info("This version needs to make some config changes. Don't worry; when prompted, your current values for existing config options will be presented (so it'll be easier to fly through the upgrade).")
154
+ m = "This version needs to make some config changes. Don't worry; " \
155
+ "when prompted, your current values for existing config options " \
156
+ "will be presented (so it'll be easier to fly through the upgrade)."
157
+ messenger.info(m)
160
158
  messenger.prompt('Press enter to continue')
161
159
  SifttterRedux.init(true)
162
160
  end
@@ -1,17 +1,17 @@
1
1
  prompts:
2
- - prompt: Where do you want to download Sifttter files to (temporarily)?
2
+ - prompt_text: Where do you want to download Sifttter files to (temporarily)?
3
3
  default: /tmp/sifttter
4
4
  config_key: sifttter_local_filepath
5
5
  config_section: sifttter_redux
6
- - prompt: Where are your Sifttter files located in Dropbox?
6
+ - prompt_text: Where are your Sifttter files located in Dropbox?
7
7
  default: /Apps/ifttt/sifttter
8
8
  config_key: sifttter_remote_filepath
9
9
  config_section: sifttter_redux
10
- - prompt: Where do you want to download Day One files to (temporarily)?
10
+ - prompt_text: Where do you want to download Day One files to (temporarily)?
11
11
  default: /tmp/dayone
12
12
  config_key: dayone_local_filepath
13
13
  config_section: sifttter_redux
14
- - prompt: Where are your Day One files located in Dropbox?
14
+ - prompt_text: Where are your Day One files located in Dropbox?
15
15
  default: /Apps/Day\ One/Journal.dayone/entries
16
16
  config_key: dayone_remote_filepath
17
17
  config_section: sifttter_redux
@@ -3,7 +3,7 @@ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'sifttter-redux/constants'
5
5
 
6
- Gem::Specification.new do |spec|
6
+ Gem::Specification.new do |spec|
7
7
  spec.name = 'sifttter-redux'
8
8
  spec.version = SifttterRedux::VERSION
9
9
  spec.authors = ['Aaron Bach']
@@ -18,15 +18,16 @@ Gem::Specification.new do |spec|
18
18
  spec.files = `git ls-files`.split("\n")
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
-
21
+
22
22
  spec.license = 'MIT'
23
23
  spec.rdoc_options = ['--charset=UTF-8']
24
24
  spec.extra_rdoc_files = %w[README.md HISTORY.md LICENSE]
25
-
25
+
26
26
  spec.add_development_dependency('rake', '10.1.1')
27
27
  spec.add_development_dependency('rdoc', '4.1.1')
28
28
  spec.add_development_dependency('aruba', '0.5.4')
29
+ spec.add_runtime_dependency('archive-zip', '0.6.0')
29
30
  spec.add_runtime_dependency('chronic', '0.10.2')
30
- spec.add_runtime_dependency('cliutils', '~> 1.3')
31
+ spec.add_runtime_dependency('cliutils', '~> 2')
31
32
  spec.add_runtime_dependency('gli','2.9.0')
32
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sifttter-redux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Bach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-13 00:00:00.000000000 Z
11
+ date: 2014-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.5.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: archive-zip
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: chronic
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +86,14 @@ dependencies:
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '1.3'
89
+ version: '2'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '1.3'
96
+ version: '2'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: gli
85
99
  requirement: !ruby/object:Gem::Requirement