chronicle-imessage 0.2.0 → 0.2.3

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
  SHA256:
3
- metadata.gz: 8e5b5b2c2b15c1a26c52871284d921960d825d24303b1d872d4d25c8d8782229
4
- data.tar.gz: 5597cc2177ae72c86c2cc9a96b75f29dc5c07b0fe2053304e0e880b4d93919c5
3
+ metadata.gz: 2be4dbec8ee2945136d579ab8d42d8580160c6eacc839d92a55a5a462f749385
4
+ data.tar.gz: c9a229903ebaffcc63fd52a480237e47f119142d3036c6a0c32513f7891ba114
5
5
  SHA512:
6
- metadata.gz: bbae018587ad66e2a3ed05a5d7e878058cfac6c747fc283fbc54995f07bbbfc6aacaeddfaa16ae6ceb9d9547f0b4c20d692ce6a4fc059d542ca4621dec0b819c
7
- data.tar.gz: ffc6247be044ebe0cfc58f545b10e7d622ebff3c82dc230c8f412abb61f971bce981bb6edcb58fbbe507a7cb8d639e8b19063ec6b66c2e332584e2c416357ab6
6
+ metadata.gz: 86dd00967c9a1a689bd575d399c0869db3b42152f7043386362caf84eaccb13a5f4c865c38546c4d6f30692629e37132687266ed284d90f2ac0141d021cba330
7
+ data.tar.gz: f3de0abf901aa6f9a2c3484f6414bd8f9d9d566c57f2ebaf4e2e3a6c74f465a1efedf6e69d88567a903c9c090a51a0e685a6c9bbeb31ad37a0c40a677c17daba
data/README.md CHANGED
@@ -13,7 +13,6 @@ IMessage importer for [chronicle-etl](https://github.com/chronicle-app/chronicle
13
13
 
14
14
  ```bash
15
15
  gem install chronicle-etl
16
- chronicle-etl connectors:install imessage
17
-
18
- chronicle-etl --extractor imessage --since:"2022-02-07" --transformer imessage --loader table
16
+ chronicle-etl plugins:install imessage
17
+ chronicle-etl --extractor imessage --since "2022-02-07" --transformer imessage
19
18
  ```
@@ -35,9 +35,9 @@ Gem::Specification.new do |spec|
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ["lib"]
37
37
 
38
- spec.add_dependency "chronicle-etl", "~> 0.4"
39
- spec.add_dependency "sqlite3", "~> 1.4.2"
40
- spec.add_dependency "phonelib", "~> 0.6.54"
38
+ spec.add_dependency "chronicle-etl", "~> 0.4.2"
39
+ spec.add_dependency "sqlite3", "~> 1.4"
40
+ spec.add_dependency "phonelib", "~> 0.6"
41
41
 
42
42
  spec.add_development_dependency "bundler", "~> 2.3"
43
43
  spec.add_development_dependency "rake", "~> 13.0.6"
@@ -1,6 +1,5 @@
1
1
  require 'chronicle/etl'
2
2
  require 'sqlite3'
3
- require 'pry'
4
3
 
5
4
  module Chronicle
6
5
  module Imessage
@@ -13,6 +12,11 @@ module Chronicle
13
12
  setting :db, default: File.join(Dir.home, 'Library', 'Messages', 'chat.db'), required: true
14
13
  setting :load_attachments, default: false
15
14
  setting :only_attachments, default: false
15
+ setting :my_phone_number
16
+ setting :my_name
17
+ setting :icloud_account_id
18
+ setting :icloud_account_dsid
19
+ setting :icloud_account_display_name
16
20
 
17
21
  def prepare
18
22
  prepare_data
@@ -23,6 +27,8 @@ module Chronicle
23
27
  meta = {}
24
28
  meta[:participants] = @chats[message['chat_id']]
25
29
  meta[:attachments] = @attachments[message['message_id']] if @attachments
30
+ meta[:my_phone_contact] = @my_phone_contact
31
+ meta[:my_icloud_account] = @my_icloud_account
26
32
 
27
33
  yield Chronicle::ETL::Extraction.new(data: message, meta: meta)
28
34
  end
@@ -36,15 +42,35 @@ module Chronicle
36
42
 
37
43
  def prepare_data
38
44
  @db = SQLite3::Database.new(@config.db, results_as_hash: true)
45
+ @local_contacts = LocalContacts.new
46
+ @contacts = @local_contacts.contacts
47
+
39
48
  @messages = load_messages
40
- @contacts = LocalContacts.new.contacts
41
49
  @chats = load_chats
42
50
 
51
+ @my_phone_contact = load_my_phone_contact(@local_contacts)
52
+ @my_icloud_account = load_my_icloud_account(@local_contacts)
53
+
43
54
  if @config.load_attachments
44
55
  @attachments = load_attachments(@messages.map{|m| m['message_id']})
45
56
  end
46
57
  end
47
58
 
59
+ def load_my_phone_contact(local_contacts)
60
+ {
61
+ phone_number: @config.my_phone_number || local_contacts.my_phone_contact.fetch(:phone_number),
62
+ name: @config.my_name || local_contacts.my_phone_contact.fetch(:full_name)
63
+ }
64
+ end
65
+
66
+ def load_my_icloud_account(local_contacts)
67
+ {
68
+ id: @config.icloud_account_id || local_contacts.my_icloud_account.fetch(:AccountID),
69
+ dsid: @config.icloud_account_dsid || local_contacts.my_icloud_account.fetch(:AccountDSID),
70
+ display_name: @config.icloud_account_display_name || @config.my_name || local_contacts.my_icloud_account.fetch(:DisplayName)
71
+ }
72
+ end
73
+
48
74
  def load_messages
49
75
  conditions = []
50
76
 
@@ -8,9 +8,6 @@ module Chronicle
8
8
  r.description = 'a row from a local imessage database'
9
9
  end
10
10
 
11
- setting :my_phone_slug, required: true
12
- setting :my_name, required: true
13
-
14
11
  def transform
15
12
  @message = @extraction.data
16
13
  @participants = @extraction.meta[:participants]
@@ -118,14 +115,40 @@ module Chronicle
118
115
  end
119
116
 
120
117
  def build_identity_mine
118
+ case identity_provider(@message['service'])
119
+ when 'icloud'
120
+ build_identity_mine_icloud
121
+ when 'phone'
122
+ build_identity_mine_phone
123
+ end
124
+ end
125
+
126
+ def build_identity_mine_icloud
127
+ icloud_account = @extraction.meta[:my_icloud_account]
128
+ raise(UntransformableRecordError, "Missing iCloud account information") unless icloud_account
129
+
121
130
  record = ::Chronicle::ETL::Models::Entity.new({
122
- represents: 'identity',
123
- slug: @config.my_phone_slug,
124
- title: @config.my_name,
125
- provider: identity_provider(@message['service']),
126
- provider_id: @message['account_guid']
131
+ represent: 'identity',
132
+ provider: 'icloud',
133
+ provider_id: icloud_account[:dsid],
134
+ title: icloud_account[:display_name],
135
+ slug: icloud_account[:id]
136
+ })
137
+ record.dedupe_on << [:provider, :represents, :slug]
138
+ record
139
+ end
140
+
141
+ def build_identity_mine_phone
142
+ phone_account = @extraction.meta[:my_phone_contact]
143
+ raise(UntransformableRecordError, "Missing own phone contact information") unless phone_account
144
+
145
+ record = ::Chronicle::ETL::Models::Entity.new({
146
+ represent: 'identity',
147
+ provider: 'phone',
148
+ title: phone_account[:name],
149
+ slug: phone_account[:phone_number]
127
150
  })
128
- record.dedupe_on = [[:represents, :slug, :provider], [:represents, :provider, :provider_id]]
151
+ record.dedupe_on << [:provider, :represents, :slug]
129
152
  record
130
153
  end
131
154
 
@@ -23,6 +23,14 @@ module Chronicle
23
23
  end
24
24
  end
25
25
 
26
+ def my_phone_contact
27
+ @my_phone_contact ||= load_my_phone_contact
28
+ end
29
+
30
+ def my_icloud_account
31
+ @my_icloud_account ||= load_my_icloud_account
32
+ end
33
+
26
34
  # The synced address book doesn't have a stable folder location so we
27
35
  # have to search for it
28
36
  def find_local_icloud_address_book
@@ -30,6 +38,38 @@ module Chronicle
30
38
  Dir.glob(pattern).first
31
39
  end
32
40
 
41
+ def load_my_icloud_account
42
+ @my_icloud_account || begin
43
+ output = `defaults read MobileMeAccounts Accounts | plutil -convert json -r -o - -- -`
44
+ JSON.parse(output, symbolize_names: true).first
45
+ end
46
+ end
47
+
48
+ def load_my_phone_contact
49
+ sql = <<-SQL
50
+ SELECT
51
+ ZABCDPHONENUMBER.ZFULLNUMBER AS identifier,
52
+ ZABCDRECORD.ZFIRSTNAME as first_name,
53
+ ZABCDRECORD.ZLASTNAME as last_name
54
+ FROM
55
+ ZABCDRECORD,
56
+ ZABCDPHONENUMBER
57
+ WHERE
58
+ ZABCDRECORD.Z_PK = ZABCDPHONENUMBER.ZOWNER
59
+ AND ZABCDRECORD.zcontainerwherecontactisme IS NOT NULL
60
+ SQL
61
+
62
+ results = @db.execute(sql)
63
+
64
+ guessed_number = results.first
65
+ return unless guessed_number
66
+
67
+ {
68
+ phone_number: Phonelib.parse(guessed_number['identifier'], "US").e164,
69
+ full_name: "#{guessed_number['first_name']} #{guessed_number['last_name']}"
70
+ }
71
+ end
72
+
33
73
  def load_phone_numbers
34
74
  sql = <<-SQL
35
75
  SELECT
@@ -1,5 +1,5 @@
1
1
  module Chronicle
2
2
  module Imessage
3
- VERSION = "0.2.0"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronicle-imessage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Louis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-25 00:00:00.000000000 Z
11
+ date: 2022-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chronicle-etl
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
19
+ version: 0.4.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.4'
26
+ version: 0.4.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.4.2
33
+ version: '1.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.4.2
40
+ version: '1.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: phonelib
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.54
47
+ version: '0.6'
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.6.54
54
+ version: '0.6'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -107,7 +107,7 @@ metadata:
107
107
  homepage_uri: https://github.com/chronicle-app/chronicle-imessage
108
108
  source_code_uri: https://github.com/chronicle-app/chronicle-imessage
109
109
  changelog_uri: https://github.com/chronicle-app/chronicle-imessage
110
- post_install_message:
110
+ post_install_message:
111
111
  rdoc_options: []
112
112
  require_paths:
113
113
  - lib
@@ -122,8 +122,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  requirements: []
125
- rubygems_version: 3.1.6
126
- signing_key:
125
+ rubygems_version: 3.3.3
126
+ signing_key:
127
127
  specification_version: 4
128
128
  summary: iMessage importer for Chronicle
129
129
  test_files: []