chronicle-safari 0.1.1 → 0.2.0

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: 00a6714d6637bd3d9566e3c55bd88c1b6adaa28f24ad90d532fbd96148e98046
4
- data.tar.gz: 54af96d1596c5a620580a8f3545a44f227ebd7ba034ce17188f9c6f151fa2ab5
3
+ metadata.gz: 7330b68fd8e6fc1a77c118d177ae175dc42567e760b34332723227bbd6f011cf
4
+ data.tar.gz: 7f6c17d05026554124eb50c52e0ca2119a3e377859b48404a81a2183883961ad
5
5
  SHA512:
6
- metadata.gz: 456c6bde7c176b653df3cbdaac209274b3face8eae1fe86b82b54386d196155584e5ff3aa9a9320acf9e92d7fbbc70ce28862f31fc707409d2201fae73b96991
7
- data.tar.gz: 115670f23e5da5c44dfaabea0e6cb100e54d0acb47cb00d61eee522b94a89c055e634c36e3f472c148caff49e7fcb6c54ead5b809940b38c87c54d7e15ec0120
6
+ metadata.gz: 94711ac7afd35f5d0427d909c75f4b3b89d7ec6075ea8e88a6242d82ebdefb7ecd19b174c9cae75e2f07651efe58d8e302bca543e3f0a564c4346af3b8a090e2
7
+ data.tar.gz: 0c3b6e5211641cddcf462daab83f1d0f787e769a8715b4f410b59fe558aee9ab9d2471284a0a9c5b0fb37ad5e4278fb637ae6aaba64a43065a5dfe89e9bfd58e
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ inherit_gem:
2
+ chronicle-core: .rubocop-plugin.yml
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Chronicle::Safari
2
+ [![Gem Version](https://badge.fury.io/rb/chronicle-safari.svg)](https://badge.fury.io/rb/chronicle-safari)
2
3
 
3
- Safri plugin for [chronicle-etl](https://github.com/chronicle-app/chronicle-etl)
4
+ Extract your Safari browser history with this plugin for [chronicle-etl](https://github.com/chronicle-app/chronicle-etl)
4
5
 
5
6
  ## Available Connectors
6
7
  ### Extractors
7
- - `safari` - Extractor for history
8
+ - `safari` - Extractor for browser history
8
9
 
9
10
  ### Transformers
10
11
  - `safari` - Transforms history into Chronicle Schema
@@ -12,8 +13,13 @@ Safri plugin for [chronicle-etl](https://github.com/chronicle-app/chronicle-etl)
12
13
  ## Usage
13
14
 
14
15
  ```sh
15
- gem install chronicle-etl
16
- chronicle-etl connectors:install safari
16
+ # Install chronicle-etl and then this plugin
17
+ $ gem install chronicle-etl
18
+ $ chronicle-etl connectors:install safari
17
19
 
18
- chronicle-etl --extractor safari --since 2022-02-07
20
+ # Extract all history
21
+ $ chronicle-etl --extractor safari
22
+
23
+ # Get last week of history and transform it into Chronicle Schema
24
+ $ chronicle-etl --extractor safari --since 1w --transformer safari
19
25
  ```
data/bin/console CHANGED
@@ -1,15 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
2
 
4
- require "bundler/setup"
5
- require "chronicle/safari"
3
+ require 'bundler/setup'
4
+ require 'chronicle/safari'
6
5
 
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
6
+ require 'pry'
7
+ Pry.start
@@ -1,45 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path("../lib", __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "chronicle/safari/version"
5
+ require 'chronicle/safari/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "chronicle-safari"
8
+ spec.name = 'chronicle-safari'
9
9
  spec.version = Chronicle::Safari::VERSION
10
- spec.authors = ["Andrew Louis"]
11
- spec.email = ["andrew@hyfen.net"]
10
+ spec.authors = ['Andrew Louis']
11
+ spec.email = ['andrew@hyfen.net']
12
12
 
13
- spec.summary = "Safari importer for Chronicle"
14
- spec.description = "Import your safari history"
15
- spec.homepage = "https://github.com/chronicle-app/chronicle-safari"
13
+ spec.summary = 'Safari importer for Chronicle'
14
+ spec.description = 'Import your safari history'
15
+ spec.homepage = 'https://github.com/chronicle-app/chronicle-safari'
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
18
  # to allow pushing to a single host or delete this section to allow pushing to any host.
19
19
  if spec.respond_to?(:metadata)
20
- spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
21
 
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = "https://github.com/chronicle-app/chronicle-safari"
24
- spec.metadata["changelog_uri"] = "https://github.com/chronicle-app/chronicle-safari"
22
+ spec.metadata['homepage_uri'] = spec.homepage
23
+ spec.metadata['source_code_uri'] = 'https://github.com/chronicle-app/chronicle-safari'
24
+ spec.metadata['changelog_uri'] = 'https://github.com/chronicle-app/chronicle-safari'
25
25
  else
26
- raise "RubyGems 2.0 or newer is required to protect against " \
27
- "public gem pushes."
26
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
27
+ 'public gem pushes.'
28
28
  end
29
29
 
30
30
  # Specify which files should be added to the gem when it is released.
31
31
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
33
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
34
  end
35
- spec.bindir = "exe"
35
+ spec.bindir = 'exe'
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
- spec.require_paths = ["lib"]
38
-
39
- spec.add_dependency "chronicle-etl", "~> 0.5"
40
- spec.add_dependency "sqlite3", "~> 1.4"
41
-
42
- spec.add_development_dependency "bundler", "~> 2.3"
43
- spec.add_development_dependency "rake", "~> 13.0.6"
44
- spec.add_development_dependency "pry-byebug", "~> 3.9"
37
+ spec.require_paths = ['lib']
38
+
39
+ spec.add_dependency 'chronicle-core', '~> 0.3'
40
+ spec.add_dependency 'chronicle-etl', '~> 0.6'
41
+ spec.add_dependency 'faraday', '~> 2'
42
+ spec.add_dependency 'omniauth-oauth2', '~> 1'
43
+ spec.add_dependency 'sqlite3', '~> 1.4'
44
+
45
+ spec.add_development_dependency 'bundler', '~> 2.3'
46
+ spec.add_development_dependency 'pry-byebug', '~> 3.10'
47
+ spec.add_development_dependency 'rake', '~> 13.0'
48
+ spec.add_development_dependency 'rubocop', '~> 1.63'
49
+ spec.metadata['rubygems_mfa_required'] = 'true'
45
50
  end
@@ -2,10 +2,12 @@ require 'chronicle/etl'
2
2
  require 'sqlite3'
3
3
 
4
4
  module Chronicle
5
- module Safari
6
- class SafariExtractor < Chronicle::ETL::Extractor
5
+ module Safari
6
+ class BrowseExtractor < Chronicle::ETL::Extractor
7
7
  register_connector do |r|
8
- r.provider = 'safari'
8
+ r.source = :safari
9
+ r.type = :browse
10
+ r.strategy = :local_db
9
11
  r.description = 'browser history'
10
12
  end
11
13
 
@@ -23,7 +25,10 @@ module Chronicle
23
25
  def extract
24
26
  @history.each do |entry|
25
27
  entry.transform_keys!(&:to_sym)
26
- yield Chronicle::ETL::Extraction.new(data: entry, meta: { icloud_account: @icloud_account } )
28
+
29
+ meta = {}
30
+ meta[:my_icloud_account] = @icloud_account
31
+ yield build_extraction(data: entry, meta:)
27
32
  end
28
33
  end
29
34
 
@@ -50,22 +55,22 @@ module Chronicle
50
55
 
51
56
  def load_history
52
57
  conditions = []
53
- conditions << "history_visits.redirect_destination IS NULL"
58
+ conditions << 'history_visits.redirect_destination IS NULL'
54
59
  conditions << "visit_time_utc > '#{@config.since.utc}'" if @config.since
55
60
  conditions << "visit_time_utc < '#{@config.until.utc}'" if @config.until
56
61
 
57
62
  sql = <<~SQL
58
63
  SELECT
59
64
  *,
60
- datetime(visit_time + 978307200, 'unixepoch') as visit_time_utc
65
+ datetime(visit_time + 978307200, 'unixepoch') as visit_time_utc
61
66
  FROM
62
- history_visits
67
+ history_visits
63
68
  LEFT JOIN
64
- history_items
65
- ON history_items.id = history_item
69
+ history_items
70
+ ON history_items.id = history_item
66
71
  SQL
67
- sql += " WHERE #{conditions.join(" AND ")}" if conditions.any?
68
- sql += " ORDER BY visit_time_utc DESC"
72
+ sql += " WHERE #{conditions.join(' AND ')}" if conditions.any?
73
+ sql += ' ORDER BY visit_time_utc DESC'
69
74
  sql += " LIMIT #{@config.limit}" if @config.limit
70
75
 
71
76
  results = @db.execute(sql)
@@ -0,0 +1,51 @@
1
+ require 'chronicle/etl'
2
+ require 'chronicle/models'
3
+
4
+ module Chronicle
5
+ module Safari
6
+ class BrowseTransformer < Chronicle::ETL::Transformer
7
+ register_connector do |r|
8
+ r.source = :safari
9
+ r.type = :browse
10
+ r.strategy = :local_db
11
+ r.description = 'a history item'
12
+ r.from_schema = :extraction
13
+ r.to_schema = :chronicle
14
+ end
15
+
16
+ def transform(record)
17
+ build_browse(record.data, record.extraction.meta[:my_icloud_account])
18
+ end
19
+
20
+ private
21
+
22
+ def build_browse(data, icloud_account)
23
+ Chronicle::Models::ViewAction.new do |r|
24
+ r.source = 'safari'
25
+ r.end_time = Time.parse(data[:visit_time_utc])
26
+ r.agent = build_agent(icloud_account)
27
+ r.object = build_site(data)
28
+ end
29
+ end
30
+
31
+ def build_site(data)
32
+ Chronicle::Models::Thing.new do |r|
33
+ r.name = data[:title]
34
+ r.url = data[:url]
35
+
36
+ r.dedupe_on = [[:url]]
37
+ end
38
+ end
39
+
40
+ def build_agent(icloud_account)
41
+ Chronicle::Models::Person.new do |r|
42
+ r.name = icloud_account[:display_name]
43
+ r.source = 'icloud'
44
+ r.slug = icloud_account[:id]
45
+ r.source_id = icloud_account[:dsid]
46
+ r.dedupe_on = [%i[type source source_id]]
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Chronicle
4
4
  module Safari
5
- VERSION = "0.1.1"
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "safari/version"
4
- require_relative "safari/safari_extractor"
5
- require_relative "safari/safari_transformer"
3
+ require_relative 'safari/version'
4
+ require_relative 'safari/browse_extractor'
5
+ require_relative 'safari/browse_transformer'
6
6
 
7
7
  module Chronicle
8
8
  module Safari
metadata CHANGED
@@ -1,29 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronicle-safari
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.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: 2022-03-25 00:00:00.000000000 Z
11
+ date: 2024-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chronicle-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: chronicle-etl
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '0.5'
33
+ version: '0.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: omniauth-oauth2
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1'
20
62
  type: :runtime
21
63
  prerelease: false
22
64
  version_requirements: !ruby/object:Gem::Requirement
23
65
  requirements:
24
66
  - - "~>"
25
67
  - !ruby/object:Gem::Version
26
- version: '0.5'
68
+ version: '1'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: sqlite3
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -52,34 +94,48 @@ dependencies:
52
94
  - - "~>"
53
95
  - !ruby/object:Gem::Version
54
96
  version: '2.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.10'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.10'
55
111
  - !ruby/object:Gem::Dependency
56
112
  name: rake
57
113
  requirement: !ruby/object:Gem::Requirement
58
114
  requirements:
59
115
  - - "~>"
60
116
  - !ruby/object:Gem::Version
61
- version: 13.0.6
117
+ version: '13.0'
62
118
  type: :development
63
119
  prerelease: false
64
120
  version_requirements: !ruby/object:Gem::Requirement
65
121
  requirements:
66
122
  - - "~>"
67
123
  - !ruby/object:Gem::Version
68
- version: 13.0.6
124
+ version: '13.0'
69
125
  - !ruby/object:Gem::Dependency
70
- name: pry-byebug
126
+ name: rubocop
71
127
  requirement: !ruby/object:Gem::Requirement
72
128
  requirements:
73
129
  - - "~>"
74
130
  - !ruby/object:Gem::Version
75
- version: '3.9'
131
+ version: '1.63'
76
132
  type: :development
77
133
  prerelease: false
78
134
  version_requirements: !ruby/object:Gem::Requirement
79
135
  requirements:
80
136
  - - "~>"
81
137
  - !ruby/object:Gem::Version
82
- version: '3.9'
138
+ version: '1.63'
83
139
  description: Import your safari history
84
140
  email:
85
141
  - andrew@hyfen.net
@@ -88,6 +144,7 @@ extensions: []
88
144
  extra_rdoc_files: []
89
145
  files:
90
146
  - ".gitignore"
147
+ - ".rubocop.yml"
91
148
  - CODE_OF_CONDUCT.md
92
149
  - Gemfile
93
150
  - README.md
@@ -96,8 +153,8 @@ files:
96
153
  - bin/setup
97
154
  - chronicle-safari.gemspec
98
155
  - lib/chronicle/safari.rb
99
- - lib/chronicle/safari/safari_extractor.rb
100
- - lib/chronicle/safari/safari_transformer.rb
156
+ - lib/chronicle/safari/browse_extractor.rb
157
+ - lib/chronicle/safari/browse_transformer.rb
101
158
  - lib/chronicle/safari/version.rb
102
159
  homepage: https://github.com/chronicle-app/chronicle-safari
103
160
  licenses: []
@@ -106,6 +163,7 @@ metadata:
106
163
  homepage_uri: https://github.com/chronicle-app/chronicle-safari
107
164
  source_code_uri: https://github.com/chronicle-app/chronicle-safari
108
165
  changelog_uri: https://github.com/chronicle-app/chronicle-safari
166
+ rubygems_mfa_required: 'true'
109
167
  post_install_message:
110
168
  rdoc_options: []
111
169
  require_paths:
@@ -121,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
179
  - !ruby/object:Gem::Version
122
180
  version: '0'
123
181
  requirements: []
124
- rubygems_version: 3.3.3
182
+ rubygems_version: 3.4.10
125
183
  signing_key:
126
184
  specification_version: 4
127
185
  summary: Safari importer for Chronicle
@@ -1,60 +0,0 @@
1
- require 'chronicle/etl'
2
-
3
- module Chronicle
4
- module Safari
5
- class SafariTransformer < Chronicle::ETL::Transformer
6
- register_connector do |r|
7
- r.provider = 'safari'
8
- r.description = 'a history item'
9
- end
10
-
11
- def transform
12
- @data = @extraction.data
13
- build_browsed
14
- end
15
-
16
- def id
17
- # IDs from local db aren't global or stable across multiple installs
18
- end
19
-
20
- def timestamp
21
- Time.parse(@data[:visit_time_utc])
22
- end
23
-
24
- private
25
-
26
- def build_browsed
27
- record = ::Chronicle::ETL::Models::Activity.new({
28
- verb: 'browsed',
29
- provider: 'safari',
30
- end_at: timestamp
31
- })
32
- record.dedupe_on << [:provider, :verb, :end_at]
33
- record.actor = build_actor
34
- record.involved = build_involved
35
- record
36
- end
37
-
38
- def build_involved
39
- record = ::Chronicle::ETL::Models::Entity.new({
40
- title: @data[:title],
41
- provider_url: @data[:url],
42
- })
43
- record.dedupe_on << [:provider_url]
44
- record
45
- end
46
-
47
- def build_actor
48
- record = ::Chronicle::ETL::Models::Entity.new({
49
- represent: 'identity',
50
- provider: 'icloud',
51
- provider_id: @extraction.meta[:icloud_account][:dsid],
52
- title: @extraction.meta[:icloud_account][:display_name],
53
- slug: @extraction.meta[:icloud_account][:id]
54
- })
55
- record.dedupe_on << [:provider, :represents, :slug]
56
- record
57
- end
58
- end
59
- end
60
- end