chronicle-email 0.2.2 → 0.3.0
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 +4 -4
- data/.rubocop.yml +2 -0
- data/Gemfile +2 -2
- data/README.md +3 -3
- data/Rakefile +2 -6
- data/bin/console +4 -11
- data/chronicle-email.gemspec +31 -24
- data/lib/chronicle/email/email_transformer.rb +59 -60
- data/lib/chronicle/email/imap_extractor.rb +28 -17
- data/lib/chronicle/email/mbox_extractor.rb +17 -10
- data/lib/chronicle/email/version.rb +1 -1
- data/lib/chronicle/email.rb +4 -4
- metadata +74 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0d66a6d2109f4f46f23fdf0c157085aed6f757f962339a422e4e38ca86ed129
|
4
|
+
data.tar.gz: e4136e05cf2827f64a07657e9442f9a8cdcac1ab88ed589c52ea76f62fd0d315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d58d42a6db25951b46a08ad44302dab836fc3063fae2b9074e5156b4db59ab147b8401b60860665a0a27394ddca98a48c58a6abdf87ce474439e4d7b179604f
|
7
|
+
data.tar.gz: b11bea8171510544c35742cb7ab72c162b7774d0bd5603a7453f065d270a230fa8b2a17d77d5bfc1205a60710f1b7d076ec4f6521630754006a5efe4e6b18fcc
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in chronicle-email.gemspec
|
6
6
|
gemspec
|
data/README.md
CHANGED
@@ -21,11 +21,11 @@ $ chronicle-etl secrets:set imap username foo@gmail.com
|
|
21
21
|
$ chronicle-etl secrets:set imap password APPPASSWORD
|
22
22
|
|
23
23
|
# Then, retrieve your email from the last five days
|
24
|
-
$ chronicle-etl --extractor email:imap --
|
24
|
+
$ chronicle-etl --extractor email:imap --schema chronicle --since 5d
|
25
25
|
|
26
26
|
# If you don't want to save your credentials as a secret, you can just pass
|
27
27
|
# them to the extractor directly
|
28
|
-
$ chronicle-etl --extractor email:imap --
|
28
|
+
$ chronicle-etl --extractor email:imap --schema chronicle --since 5d --loader json \
|
29
29
|
--extractor-opts username:foo@gmail.com --password:APPPASSWORD
|
30
30
|
```
|
31
31
|
|
@@ -34,7 +34,7 @@ The MBOX format is used to archive an email mailbox. [Google Takeout](https://ta
|
|
34
34
|
|
35
35
|
```sh
|
36
36
|
# Retrieve the subject lines of all emails in test.mbox
|
37
|
-
$ chronicle-etl --extractor email:mbox --input inbox.mbox --
|
37
|
+
$ chronicle-etl --extractor email:mbox --input ~/Downloads/inbox.mbox --fields subject
|
38
38
|
```
|
39
39
|
|
40
40
|
## Available Connectors
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'chronicle/email'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
6
|
+
require 'pry'
|
7
|
+
Pry.start
|
data/chronicle-email.gemspec
CHANGED
@@ -1,47 +1,54 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require 'chronicle/email/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'chronicle-email'
|
8
7
|
spec.version = Chronicle::Email::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['Andrew Louis']
|
9
|
+
spec.email = ['andrew@hyfen.net']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
11
|
+
spec.summary = 'Email importer for Chronicle'
|
12
|
+
spec.description = 'Various email importers for chronicle-etl'
|
13
|
+
spec.homepage = 'https://github.com/chronicle-app/chronicle-email'
|
14
|
+
spec.license = 'MIT'
|
16
15
|
|
17
16
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
17
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
18
|
if spec.respond_to?(:metadata)
|
20
19
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
20
|
|
22
|
-
spec.metadata[
|
23
|
-
spec.metadata[
|
24
|
-
spec.metadata[
|
21
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
22
|
+
spec.metadata['source_code_uri'] = 'https://github.com/chronicle-app/chronicle-email'
|
23
|
+
spec.metadata['changelog_uri'] = 'https://github.com/chronicle-app/chronicle-email'
|
25
24
|
else
|
26
|
-
raise
|
27
|
-
|
25
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
26
|
+
'public gem pushes.'
|
28
27
|
end
|
29
28
|
|
30
29
|
# Specify which files should be added to the gem when it is released.
|
31
30
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
-
spec.files
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
33
32
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
33
|
end
|
35
|
-
spec.bindir =
|
34
|
+
spec.bindir = 'exe'
|
36
35
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
-
spec.require_paths = [
|
36
|
+
spec.require_paths = ['lib']
|
37
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
38
|
+
spec.required_ruby_version = '>= 3.1'
|
38
39
|
|
39
|
-
spec.add_dependency "chronicle-etl", "~> 0.5"
|
40
|
-
spec.add_dependency "mail", "~> 2.7"
|
41
40
|
spec.add_dependency 'email_reply_parser', '~> 0.5'
|
41
|
+
spec.add_dependency 'mail', '~> 2.7'
|
42
42
|
spec.add_dependency 'reverse_markdown', '~> 2.0'
|
43
|
-
|
44
|
-
|
45
|
-
spec.
|
46
|
-
spec.
|
43
|
+
# Needed for Ruby 3.1 compatibility (https://github.com/mikel/mail/pull/1439#issuecomment-1002801221)
|
44
|
+
# TODO: check back for new version of `mail`
|
45
|
+
spec.add_dependency 'chronicle-core', '~> 0.3'
|
46
|
+
spec.add_dependency 'chronicle-etl', '~> 0.6'
|
47
|
+
spec.add_dependency 'net-imap'
|
48
|
+
spec.add_dependency 'net-smtp'
|
49
|
+
|
50
|
+
spec.add_development_dependency 'bundler', '~> 2.3'
|
51
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.10'
|
52
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
53
|
+
spec.add_development_dependency 'rubocop', '~> 1.63'
|
47
54
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'chronicle/etl'
|
2
|
-
require '
|
2
|
+
require 'chronicle/models'
|
3
3
|
require 'timeout'
|
4
4
|
require 'email_reply_parser'
|
5
5
|
require 'reverse_markdown'
|
@@ -8,98 +8,97 @@ module Chronicle
|
|
8
8
|
module Email
|
9
9
|
class EmailTransformer < Chronicle::ETL::Transformer
|
10
10
|
register_connector do |r|
|
11
|
+
r.source = :email
|
12
|
+
r.type = :message
|
11
13
|
r.description = 'an email object'
|
12
|
-
r.
|
13
|
-
r.
|
14
|
+
r.from_schema = :extraction
|
15
|
+
r.to_schema = :chronicle
|
14
16
|
end
|
15
17
|
|
16
18
|
setting :body_as_markdown, default: false
|
17
19
|
setting :remove_signature, default: true
|
18
20
|
|
19
|
-
def transform
|
20
|
-
build_messaged
|
21
|
+
def transform(record)
|
22
|
+
build_messaged(record.data[:raw])
|
21
23
|
end
|
22
24
|
|
23
|
-
|
24
|
-
message.message_id || raise(Chronicle::ETL::UntransformableRecordError, "Email doesn't have an ID")
|
25
|
-
end
|
25
|
+
private
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
27
|
+
def build_messaged(email)
|
28
|
+
timestamp = email.date&.to_time || raise(Chronicle::ETL::UntransformableRecordError,
|
29
|
+
"Email doesn't have a timestamp")
|
30
30
|
|
31
|
-
|
31
|
+
email.message_id || raise(Chronicle::ETL::UntransformableRecordError, "Email doesn't have an ID")
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
Chronicle::Models::CommunicateAction.new do |r|
|
34
|
+
r.end_time = timestamp
|
35
|
+
r.agent = build_agent(email[:from])
|
36
|
+
r.source = 'email'
|
37
|
+
r.source_id = email.message_id
|
38
|
+
r.object = build_message(email)
|
39
|
+
end
|
35
40
|
end
|
36
41
|
|
37
|
-
def
|
38
|
-
|
39
|
-
record.verb = 'messaged'
|
40
|
-
record.provider = 'email'
|
41
|
-
record.provider_id = id
|
42
|
-
record.end_at = timestamp
|
42
|
+
def build_agent(from)
|
43
|
+
raise(Chronicle::ETL::UntransformableRecordError, "Can't determine email sender") unless from&.addrs&.any?
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
record.actor = build_actor
|
47
|
-
record.involved = build_message
|
48
|
-
record
|
45
|
+
build_person(from.addrs.first)
|
49
46
|
end
|
50
47
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
def build_message(email)
|
49
|
+
Chronicle::Models::Message.new do |r|
|
50
|
+
r.name = clean_subject(email.subject)
|
51
|
+
r.text = clean_body(email)
|
52
|
+
r.source = 'email'
|
53
|
+
r.source_id = email.message_id
|
55
54
|
|
56
|
-
|
57
|
-
record.represents = 'identity'
|
58
|
-
record.provider = 'email'
|
59
|
-
record.slug = message[:from].addrs.first.address
|
60
|
-
record.title = message[:from].addrs.first.display_name
|
55
|
+
r.recipient = email[:to]&.addrs&.map { |addr| build_person(addr) }
|
61
56
|
|
62
|
-
|
57
|
+
# TODO: handle email references
|
58
|
+
# TODO: handle email account owner
|
59
|
+
# TODO: handle attachments
|
63
60
|
|
64
|
-
|
61
|
+
r.dedupe_on << %i[source source_id type]
|
62
|
+
end
|
65
63
|
end
|
66
64
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
# TODO: handle consumer
|
76
|
-
# TODO: handle email references
|
77
|
-
# TODO: handle email account owner
|
78
|
-
# TODO: handle attachments
|
79
|
-
|
80
|
-
record
|
65
|
+
def build_person(addr)
|
66
|
+
Chronicle::Models::Person.new do |r|
|
67
|
+
r.source = 'email'
|
68
|
+
r.slug = addr.address
|
69
|
+
r.name = addr.display_name
|
70
|
+
r.dedupe_on << %i[represents provider slug]
|
71
|
+
end
|
81
72
|
end
|
82
73
|
|
83
74
|
def clean_subject(subject)
|
84
|
-
subject&.encode(
|
75
|
+
subject&.encode('UTF-8', invalid: :replace, undef: :replace)
|
85
76
|
end
|
86
77
|
|
87
|
-
def clean_body
|
88
|
-
# FIXME: this all needs to be refactored
|
78
|
+
def clean_body(message)
|
79
|
+
# FIXME: this all needs to be refactored
|
89
80
|
if message.multipart?
|
90
|
-
body =
|
81
|
+
body = begin
|
82
|
+
message.text_part&.decoded
|
83
|
+
rescue StandardError
|
84
|
+
Mail::UnknownEncodingType
|
85
|
+
end
|
91
86
|
else
|
92
|
-
body =
|
87
|
+
body = begin
|
88
|
+
message.body&.decoded
|
89
|
+
rescue StandardError
|
90
|
+
Mail::UnknownEncodingType
|
91
|
+
end
|
93
92
|
body = body_to_markdown if @config.body_as_markdown
|
94
93
|
end
|
95
94
|
|
96
95
|
return if body == Mail::UnknownEncodingType
|
97
|
-
return unless body && body !=
|
96
|
+
return unless body && body != ''
|
98
97
|
|
99
98
|
body = body_without_signature(body) if @config.remove_signature
|
100
99
|
|
101
100
|
# Force UTF-8 encoding
|
102
|
-
body.encode(
|
101
|
+
body.encode('UTF-8', invalid: :replace, undef: :replace)
|
103
102
|
end
|
104
103
|
|
105
104
|
def body_to_markdown(body)
|
@@ -111,11 +110,11 @@ module Chronicle
|
|
111
110
|
def body_without_signature(body)
|
112
111
|
# FIXME: regex in EmailReplyParse gem seems to get into infinite loops
|
113
112
|
# with certain long bodies that have binary data
|
114
|
-
|
113
|
+
Timeout.timeout(5) do
|
115
114
|
EmailReplyParser.parse_reply(body)
|
116
115
|
end
|
117
|
-
rescue Timeout::Error, StandardError
|
118
|
-
|
116
|
+
rescue Timeout::Error, StandardError
|
117
|
+
body
|
119
118
|
end
|
120
119
|
end
|
121
120
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'net/imap'
|
2
|
+
require 'mail'
|
2
3
|
|
3
4
|
module Chronicle
|
4
5
|
module Email
|
5
6
|
class IMAPExtractor < Chronicle::ETL::Extractor
|
6
7
|
register_connector do |r|
|
7
|
-
r.
|
8
|
-
r.
|
9
|
-
r.
|
8
|
+
r.source = :email
|
9
|
+
r.type = :message
|
10
|
+
r.strategy = :imap
|
11
|
+
r.description = 'IMAP server'
|
10
12
|
end
|
11
13
|
|
12
14
|
setting :host, required: true, default: 'imap.gmail.com'
|
@@ -28,7 +30,15 @@ module Chronicle
|
|
28
30
|
def extract
|
29
31
|
@message_ids.each do |message_id|
|
30
32
|
message = fetch_message(message_id)
|
31
|
-
|
33
|
+
email = Mail.new(message.attr['BODY[]'])
|
34
|
+
data = {
|
35
|
+
raw: email,
|
36
|
+
time: email.date&.to_time,
|
37
|
+
subject: email.subject,
|
38
|
+
from: email&.from&.join(', '),
|
39
|
+
to: email&.to&.join(', ')
|
40
|
+
}
|
41
|
+
yield build_extraction(data:)
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
@@ -39,31 +49,32 @@ module Chronicle
|
|
39
49
|
connection.login(@config.username, @config.password)
|
40
50
|
connection.select(@config.mailbox)
|
41
51
|
connection
|
42
|
-
rescue Net::IMAP::NoResponseError
|
43
|
-
raise(Chronicle::ETL::ExtractionError,
|
52
|
+
rescue Net::IMAP::NoResponseError
|
53
|
+
raise(Chronicle::ETL::ExtractionError, 'Error connecting to IMAP server. Please check username and password')
|
44
54
|
end
|
45
55
|
|
46
56
|
def fetch_message_ids
|
47
57
|
keys = gmail_mode? ? search_keys_gmail : search_keys_default
|
48
|
-
@connection.search(keys)
|
49
|
-
|
50
|
-
|
58
|
+
message_ids = @connection.search(keys)
|
59
|
+
message_ids = message_ids.first(@config.limit) if @config.limit
|
60
|
+
message_ids
|
61
|
+
rescue Net::IMAP::BadResponseError
|
62
|
+
raise(Chronicle::ETL::ExtractionError, 'Error searching IMAP server for messages')
|
51
63
|
end
|
52
64
|
|
53
65
|
def fetch_message(message_id)
|
54
|
-
response = @connection.fetch(
|
55
|
-
raise(Chronicle::ETL::ExtractionError,
|
66
|
+
response = @connection.fetch(message_id, 'BODY.PEEK[]')
|
67
|
+
raise(Chronicle::ETL::ExtractionError, 'Error loading message') unless response
|
56
68
|
|
57
|
-
|
69
|
+
response[0]
|
58
70
|
end
|
59
71
|
|
60
72
|
def search_keys_gmail
|
61
73
|
# Gmail offers an extension to IMAP that lets us use gmail queries
|
62
|
-
q = ""
|
63
74
|
|
64
75
|
# First, we ignore drafts beacuse they break a lot of assumptions we
|
65
76
|
# make when when processing emails (lack of timestamps, ids, etc)
|
66
|
-
q =
|
77
|
+
q = '-label:draft'
|
67
78
|
|
68
79
|
# We use UNIX timestamps in gmail filters which let us do more precise
|
69
80
|
# since/until compared with date-based imap filters
|
@@ -71,14 +82,14 @@ module Chronicle
|
|
71
82
|
q += " before:#{@config.until.to_i}" if @config.until
|
72
83
|
q += " #{@config.search_query}" if @config.search_query
|
73
84
|
|
74
|
-
[
|
85
|
+
['X-GM-RAW', q]
|
75
86
|
end
|
76
87
|
|
77
88
|
def search_keys_default
|
78
89
|
keys = []
|
79
90
|
# TODO: test out non-gmail IMAP searching (for @config.search_query)
|
80
91
|
keys += ['SINCE', Net::IMAP.format_date(@config.since)] if @config.since
|
81
|
-
keys
|
92
|
+
keys + ['BEFORE', Net::IMAP.format_date(@config.until)] if @config.until
|
82
93
|
end
|
83
94
|
|
84
95
|
def gmail_mode?
|
@@ -86,4 +97,4 @@ module Chronicle
|
|
86
97
|
end
|
87
98
|
end
|
88
99
|
end
|
89
|
-
end
|
100
|
+
end
|
@@ -6,9 +6,10 @@ module Chronicle
|
|
6
6
|
module Email
|
7
7
|
class MboxExtractor < Chronicle::ETL::Extractor
|
8
8
|
register_connector do |r|
|
9
|
-
r.
|
9
|
+
r.source = :email
|
10
|
+
r.type = :message
|
11
|
+
r.strategy = :mbox
|
10
12
|
r.description = 'an .mbox file'
|
11
|
-
r.identifier = 'mbox'
|
12
13
|
end
|
13
14
|
|
14
15
|
setting :input, required: true
|
@@ -40,14 +41,20 @@ module Chronicle
|
|
40
41
|
#
|
41
42
|
# TODO: make this thread-safe (one tmp file per email?)
|
42
43
|
file.each do |line|
|
43
|
-
if line =~ NEW_EMAIL_REGEX
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
if line =~ (NEW_EMAIL_REGEX) && File.size(tmp).positive?
|
45
|
+
tmp.rewind
|
46
|
+
|
47
|
+
email = Mail.new(tmp.read)
|
48
|
+
data = {
|
49
|
+
raw: email,
|
50
|
+
time: email.date&.to_time,
|
51
|
+
subject: email.subject,
|
52
|
+
from: email&.from&.join(', '),
|
53
|
+
to: email&.to&.join(', ')
|
54
|
+
}
|
55
|
+
yield build_extraction(data:)
|
56
|
+
tmp.truncate(0)
|
57
|
+
tmp.rewind
|
51
58
|
end
|
52
59
|
tmp.write(line)
|
53
60
|
end
|
data/lib/chronicle/email.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'chronicle/email/version'
|
2
|
+
require 'chronicle/email/email_transformer'
|
3
|
+
require 'chronicle/email/mbox_extractor'
|
4
|
+
require 'chronicle/email/imap_extractor'
|
5
5
|
|
6
6
|
module Chronicle
|
7
7
|
module Email
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chronicle-email
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Louis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: email_reply_parser
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
@@ -39,47 +39,103 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: reverse_markdown
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
47
|
+
version: '2.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
54
|
+
version: '2.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: chronicle-core
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0.3'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: chronicle-etl
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: net-imap
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: net-smtp
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: bundler
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
72
114
|
requirements:
|
73
115
|
- - "~>"
|
74
116
|
- !ruby/object:Gem::Version
|
75
|
-
version: '2.
|
117
|
+
version: '2.3'
|
76
118
|
type: :development
|
77
119
|
prerelease: false
|
78
120
|
version_requirements: !ruby/object:Gem::Requirement
|
79
121
|
requirements:
|
80
122
|
- - "~>"
|
81
123
|
- !ruby/object:Gem::Version
|
82
|
-
version: '2.
|
124
|
+
version: '2.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.10'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.10'
|
83
139
|
- !ruby/object:Gem::Dependency
|
84
140
|
name: rake
|
85
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +151,19 @@ dependencies:
|
|
95
151
|
- !ruby/object:Gem::Version
|
96
152
|
version: '13.0'
|
97
153
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
154
|
+
name: rubocop
|
99
155
|
requirement: !ruby/object:Gem::Requirement
|
100
156
|
requirements:
|
101
157
|
- - "~>"
|
102
158
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
159
|
+
version: '1.63'
|
104
160
|
type: :development
|
105
161
|
prerelease: false
|
106
162
|
version_requirements: !ruby/object:Gem::Requirement
|
107
163
|
requirements:
|
108
164
|
- - "~>"
|
109
165
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
166
|
+
version: '1.63'
|
111
167
|
description: Various email importers for chronicle-etl
|
112
168
|
email:
|
113
169
|
- andrew@hyfen.net
|
@@ -117,6 +173,7 @@ extra_rdoc_files: []
|
|
117
173
|
files:
|
118
174
|
- ".gitignore"
|
119
175
|
- ".rspec"
|
176
|
+
- ".rubocop.yml"
|
120
177
|
- ".travis.yml"
|
121
178
|
- CODE_OF_CONDUCT.md
|
122
179
|
- Gemfile
|
@@ -138,6 +195,7 @@ metadata:
|
|
138
195
|
homepage_uri: https://github.com/chronicle-app/chronicle-email
|
139
196
|
source_code_uri: https://github.com/chronicle-app/chronicle-email
|
140
197
|
changelog_uri: https://github.com/chronicle-app/chronicle-email
|
198
|
+
rubygems_mfa_required: 'true'
|
141
199
|
post_install_message:
|
142
200
|
rdoc_options: []
|
143
201
|
require_paths:
|
@@ -146,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
204
|
requirements:
|
147
205
|
- - ">="
|
148
206
|
- !ruby/object:Gem::Version
|
149
|
-
version: '
|
207
|
+
version: '3.1'
|
150
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
209
|
requirements:
|
152
210
|
- - ">="
|
153
211
|
- !ruby/object:Gem::Version
|
154
212
|
version: '0'
|
155
213
|
requirements: []
|
156
|
-
rubygems_version: 3.
|
214
|
+
rubygems_version: 3.4.10
|
157
215
|
signing_key:
|
158
216
|
specification_version: 4
|
159
217
|
summary: Email importer for Chronicle
|