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.
- checksums.yaml +7 -0
- data/lib/capture_thing_import.rb +164 -0
- 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: []
|