doing-plugin-capture-thing-import 0.0.1

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/capture_thing_import.rb +164 -0
  3. metadata +57 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bbfbc3597d88b444659230717e6fa28b8c723ad7a9b6785e374b2ed030aa3c38
4
+ data.tar.gz: 434904ac94491696e00214b6d89b534b9b9591a52bd45eafc3a4e9224b2be696
5
+ SHA512:
6
+ metadata.gz: b678f3de4828bca64924176135435a88f0204a6822ebd530b4de30183b75c3059b9723ea7e450e1afabe1c1aa4e32a105563b63cfe0674105ff55a920cd8542c
7
+ data.tar.gz: 88b8e9b6e4d2c60a9037632c8f19531dda3d933b31bb29c616f5a7101c56b84b503423eb254ae4754c9ef8f057f0a1d53525e925b9af573157c92aa4a543ef0d
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ # title: Capture Thing Import
4
+ # description: Import entries from a Capture Thing folder
5
+ # author: Brett Terpstra
6
+ # url: https://brettterpstra.com
7
+ module Doing
8
+ # Capture Thing import plugin
9
+ class CaptureThingImport
10
+ require 'time'
11
+ require 'twitter'
12
+ include Doing::Util
13
+ include Doing::Errors
14
+
15
+ def self.settings
16
+ {
17
+ trigger: '^cap(?:ture)?(:?thing)?'
18
+ }
19
+ end
20
+
21
+ ##
22
+ ## Imports a Capture Thing folder
23
+ ##
24
+ ## @param wwid [WWID] WWID object
25
+ ## @param path [String] Path to Capture Thing folder
26
+ ## @param options [Hash] Additional Options
27
+ ##
28
+ def self.import(wwid, path, options: {})
29
+ raise InvalidArgument, 'Path to Capture Thing folder required' if path.nil?
30
+
31
+ path = File.expand_path(path)
32
+
33
+ raise InvalidArgument, 'File not found' unless File.exist?(path)
34
+
35
+ raise InvalidArgument, 'Path is not a directory' unless File.directory?(path)
36
+
37
+ options[:no_overlap] ||= false
38
+ options[:autotag] ||= wwid.auto_tag
39
+
40
+ tags = options[:tag] ? options[:tag].split(/[ ,]+/).map { |t| t.sub(/^@?/, '') } : []
41
+ options[:tag] = nil
42
+ prefix = options[:prefix] || ''
43
+
44
+ @old_items = wwid.content
45
+
46
+ new_items = read_capture_folder(path)
47
+
48
+ total = new_items.count
49
+
50
+ options[:count] = 0
51
+
52
+ new_items = wwid.filter_items(new_items, opt: options)
53
+
54
+ skipped = total - new_items.count
55
+ Doing.logger.debug('Skipped:' , %(#{skipped} items that didn't match filter criteria)) if skipped.positive?
56
+
57
+ imported = []
58
+
59
+ new_items.each do |item|
60
+ next if duplicate?(item)
61
+
62
+ title = "#{prefix} #{item.title}"
63
+ tags.each do |tag|
64
+ if title =~ /\b#{tag}\b/i
65
+ title.sub!(/\b#{tag}\b/i, "@#{tag}")
66
+ else
67
+ title += " @#{tag}"
68
+ end
69
+ end
70
+ title = wwid.autotag(title) if options[:autotag]
71
+ title.gsub!(/ +/, ' ')
72
+ title.strip!
73
+ section = options[:section] || item.section
74
+ section ||= wwid.config['current_section']
75
+
76
+ new_item = Item.new(item.date, title, section)
77
+ new_item.note = item.note
78
+
79
+ imported.push(new_item)
80
+ end
81
+
82
+ dups = new_items.count - imported.count
83
+ Doing.logger.info('Skipped:', %(#{dups} duplicate items)) if dups.positive?
84
+
85
+ imported = wwid.dedup(imported, no_overlap: !options[:overlap])
86
+ overlaps = new_items.count - imported.count - dups
87
+ Doing.logger.debug('Skipped:', "#{overlaps} items with overlapping times") if overlaps.positive?
88
+
89
+ imported.each do |item|
90
+ wwid.content.add_section(item.section)
91
+ wwid.content.push(item)
92
+ end
93
+
94
+ Doing.logger.info('Imported:', "#{imported.count} items")
95
+ end
96
+
97
+ def self.duplicate?(item)
98
+ @old_items.each do |oi|
99
+ return true if item.equal?(oi)
100
+ end
101
+
102
+ false
103
+ end
104
+
105
+ def self.parse_entry(date, entry)
106
+ lines = entry.strip.split(/\n/)
107
+
108
+ return nil if lines.nil?
109
+
110
+ time_line = lines.shift
111
+
112
+ return nil unless time_line =~ /^# (\d+:\d{2} [AP]M)/
113
+
114
+ m = time_line.match(/^# (\d+:\d{2} [AP]M)/)
115
+
116
+ unless m
117
+ Doing.logger.debug("Error parsing time #{time_line}")
118
+ return nil
119
+ end
120
+
121
+ time = m[1]
122
+ entry_date = Time.parse("#{date} #{time}")
123
+
124
+ title = ''
125
+ note = Note.new
126
+ lines.each_with_index do |l, i|
127
+ if l =~ /^-{4,}/
128
+ note.add(lines.slice(i + 1, lines.count - i))
129
+ break
130
+ else
131
+ title += l
132
+ end
133
+ end
134
+
135
+ Item.new(entry_date, title, nil, note)
136
+ end
137
+
138
+ def self.read_capture_folder(path)
139
+ folder = File.expand_path(path)
140
+
141
+ return nil unless File.exist?(folder) && File.directory?(folder)
142
+
143
+ items = []
144
+
145
+ files = Dir.glob('**/*.md', base: folder)
146
+
147
+ files.each do |file|
148
+ date = File.basename(file, '.md').match(/^(\d{4}-\d{2}-\d{2})/)[1]
149
+ input = IO.read(File.join(folder, file))
150
+ input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
151
+ entries = input.split(/^\* \* \* \* \*$/).map(&:strip).delete_if(&:empty?)
152
+
153
+ entries.each do |entry|
154
+ new_entry = parse_entry(date, entry)
155
+ items << new_entry if new_entry
156
+ end
157
+ end
158
+
159
+ items
160
+ end
161
+
162
+ Doing::Plugins.register 'capturething', :import, self
163
+ end
164
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: doing-plugin-capture-thing-import
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brett Terpstra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: twitter
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ description: Imports entries from the Capture Thing folder
28
+ email: me@brettterpstra.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/capture_thing_import.rb
34
+ homepage: https://brettterpstra.com
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 3.2.16
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Capture Thing import for Doing
57
+ test_files: []