chronicle-imessage 0.2.0 → 0.2.3

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
  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: []