chronicle-pinboard 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: 290728f6a7dcff698aba9ba5e636e6da3ee0074d073926ade6a6d8841fbec859
4
- data.tar.gz: 1a8e7e70b604e7c71b37e05cd95dbd001459b7c1682ae1e03d97146a50db48fb
3
+ metadata.gz: c3ca6b04d95423377e1b2b2d5fc935ae991917e7f29bbb21174e9412eb6c0251
4
+ data.tar.gz: 78166200e312683229681764e3b43c99b16eb2359df2e3b019814f14adf21571
5
5
  SHA512:
6
- metadata.gz: 866eb3508e2aa678690a55b70d40ce5d6d6d64b3b8fe036fcd2e77f911ff4f86952e033eaabb33e8b68b0261540f6e1b453490021078a3993b14979dd62903a7
7
- data.tar.gz: 8dacd215171fb01db26c7d8a9956237f1af07625d58f167030ae3808898b06c42e78f183e0b4db348b6e7b84682ead9d47f271463210585a565c044923c5236d
6
+ metadata.gz: 735e34e238f0f2ff2f455b985484c4e4434372fc7293c20efa90a24327131dd303082f8d8fb9a315fca5cf1571c5c2f7f53bd41dcd8291c1b34b0738e0a62fe7
7
+ data.tar.gz: a5b7bc6653435128cd375e71a0c9a5045c74118567032ab323fd9d2878f45ba29d673d86cb1c0e959ce389dd031135b7471d7b19af73a268aefa7c80ce6bc198
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ inherit_gem:
2
+ chronicle-core: .rubocop-plugin.yml
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  source "https://rubygems.org"
4
2
 
5
3
  # Specify your gem's dependencies in chronicle-pinboard.gemspec
data/README.md CHANGED
@@ -13,11 +13,12 @@ Extract your Pinboard bookmarks using the command line with this plugin for [chr
13
13
  ## Usage
14
14
 
15
15
  ```sh
16
- gem install chronicle-etl
17
- chronicle-etl connectors:install pinboard
16
+ $ gem install chronicle-etl
17
+ $ chronicle-etl plugins:install pinboard
18
+
19
+ # You can get a pinboard access token from https://pinboard.in/settings/password
20
+ $ chronicle-etl secrets:set pinboard access_token PINBOARD_ACCESS_TOKEN
18
21
 
19
- # You can get PINBOARD_ACCESS_TOKEN from https://pinboard.in/settings/password
20
22
  # Extract pinboard bookmarks from the last 10 days
21
- chronicle-etl --extractor pinboard --extractor-opts access_token:$PINBOARD_ACCESS_TOKEN --since 10d
23
+ $ chronicle-etl --extractor pinboard --since 10d
22
24
  ```
23
-
data/Rakefile CHANGED
@@ -1,4 +1,2 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
4
2
  task default: %i[]
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/pinboard"
3
+ require 'bundler/setup'
4
+ require 'chronicle/pinboard'
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,48 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
4
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "chronicle/pinboard/version"
3
+ require 'chronicle/pinboard/version'
6
4
 
7
5
  Gem::Specification.new do |spec|
8
- spec.name = "chronicle-pinboard"
6
+ spec.name = 'chronicle-pinboard'
9
7
  spec.version = Chronicle::Pinboard::VERSION
10
- spec.authors = ["Andrew Louis"]
11
- spec.email = ["andrew@hyfen.net"]
8
+ spec.authors = ['Andrew Louis']
9
+ spec.email = ['andrew@hyfen.net']
12
10
 
13
- spec.summary = "Pinboard importer for Chronicle"
14
- spec.description = "Import your Pinboard bookmarks"
15
- spec.homepage = "https://github.com/chronicle-app/chronicle-pinboard"
11
+ spec.summary = 'Pinboard importer for Chronicle'
12
+ spec.description = 'Import your Pinboard bookmarks'
13
+ spec.homepage = 'https://github.com/chronicle-app/chronicle-pinboard'
16
14
 
17
15
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
16
  # to allow pushing to a single host or delete this section to allow pushing to any host.
19
17
  if spec.respond_to?(:metadata)
20
- spec.metadata['allowed_push_host'] = "https://rubygems.org"
18
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
19
 
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = "https://github.com/chronicle-app/chronicle-pinboard"
24
- spec.metadata["changelog_uri"] = "https://github.com/chronicle-app/chronicle-pinboard"
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] = 'https://github.com/chronicle-app/chronicle-pinboard'
22
+ spec.metadata['changelog_uri'] = 'https://github.com/chronicle-app/chronicle-pinboard'
25
23
  else
26
- raise "RubyGems 2.0 or newer is required to protect against " \
27
- "public gem pushes."
24
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
25
+ 'public gem pushes.'
28
26
  end
29
27
 
30
28
  # Specify which files should be added to the gem when it is released.
31
29
  # 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
30
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
31
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
32
  end
35
- spec.bindir = "exe"
33
+ spec.bindir = 'exe'
36
34
  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 "faraday", "~> 2.2"
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"
35
+ spec.require_paths = ['lib']
36
+ spec.metadata['rubygems_mfa_required'] = 'true'
37
+
38
+ spec.add_dependency 'chronicle-core', '~> 0.3'
39
+ spec.add_dependency 'chronicle-etl', '~> 0.6'
40
+ spec.add_dependency 'faraday', '~> 2'
41
+ spec.add_dependency 'omniauth-oauth2', '~> 1'
42
+ spec.add_dependency 'sqlite3', '~> 1.4'
43
+
44
+ spec.add_development_dependency 'bundler', '~> 2.3'
45
+ spec.add_development_dependency 'pry-byebug', '~> 3.10'
46
+ spec.add_development_dependency 'rake', '~> 13.0'
47
+ spec.add_development_dependency 'rubocop', '~> 1.63'
45
48
  end
@@ -2,25 +2,27 @@ require 'chronicle/etl'
2
2
  require 'faraday'
3
3
 
4
4
  module Chronicle
5
- module Pinboard
5
+ module Pinboard
6
6
  class PinboardExtractor < Chronicle::ETL::Extractor
7
7
  register_connector do |r|
8
- r.provider = 'pinboard'
9
- r.description = 'bookmarks'
8
+ r.source = :pinboard
9
+ r.type = :bookmark
10
+ r.strategy = :api
11
+ r.description = 'a bookmark from pinboard'
10
12
  end
11
13
 
12
14
  setting :access_token, required: true
13
15
 
14
16
  def prepare
15
- raise(Chronicle::ETL::ExtractionError, "Access token is missing") if @config.access_token.empty?
17
+ raise(Chronicle::ETL::ExtractionError, 'Access token is missing') if @config.access_token.empty?
16
18
 
17
19
  @bookmarks = load_bookmarks
18
- @username = @config.access_token.split(":").first
20
+ @username = @config.access_token.split(':').first
19
21
  end
20
22
 
21
23
  def extract
22
24
  @bookmarks.each do |bookmark|
23
- yield Chronicle::ETL::Extraction.new(data: bookmark, meta: { username: @username })
25
+ yield build_extraction(data: bookmark, meta: { username: @username })
24
26
  end
25
27
  end
26
28
 
@@ -34,18 +36,19 @@ module Chronicle
34
36
  params = {
35
37
  auth_token: @config.access_token,
36
38
  format: 'json',
37
- meta: true,
39
+ meta: true
38
40
  }
39
41
  params[:fromdt] = @config.since.utc.iso8601 if @config.since
40
42
 
41
43
  conn = Faraday.new(
42
44
  url: 'https://api.pinboard.in/',
43
- params: params
45
+ params:
44
46
  )
45
47
 
46
48
  response = conn.get('/v1/posts/all')
47
49
  bookmarks = JSON.parse(response.body, { symbolize_names: true })
48
50
  bookmarks = bookmarks.keep_if { |bookmark| Time.parse(bookmark[:time]) < @config.until } if @config.until
51
+ bookmarks = bookmarks.first(@config.limit) if @config.limit
49
52
  bookmarks
50
53
  end
51
54
  end
@@ -1,98 +1,85 @@
1
1
  require 'chronicle/etl'
2
+ require 'chronicle/models'
2
3
 
3
4
  module Chronicle
4
5
  module Pinboard
5
6
  class PinboardTransformer < Chronicle::ETL::Transformer
6
7
  register_connector do |r|
7
- r.provider = 'pinboard'
8
- r.description = 'bookmark from pinboard'
8
+ r.source = :pinboard
9
+ r.type = :bookmark
10
+ r.strategy = :api
11
+ r.description = 'a booknark from pinboard'
12
+ r.from_schema = :extraction
13
+ r.to_schema = :chronicle
9
14
  end
10
15
 
11
- def transform
12
- @bookmark = @extraction.data
13
- build_liked
14
- end
16
+ def transform(record)
17
+ site = build_site(record.data)
18
+ agent = build_agent(record.extraction.meta[:username])
19
+ id = record.data[:hash]
20
+ end_time = Time.parse(record.data[:time])
15
21
 
16
- def timestamp
17
- Time.parse(@bookmark[:time])
18
- end
22
+ actions = []
19
23
 
20
- def id
21
- @bookmark[:hash]
22
- end
24
+ actions << build_bookmark(site:, agent:, id:, end_time:)
23
25
 
24
- private
26
+ note = record.data[:extended]
27
+ actions << build_comment(site:, agent:, id:, end_time:, note:) if note.size.positive?
25
28
 
26
- def build_liked
27
- record = ::Chronicle::ETL::Models::Activity.new
28
- record.end_at = timestamp
29
- record.verb = 'liked'
30
- record.provider_id = id
31
- record.provider = 'pinboard'
32
- record.dedupe_on = [[:provider, :verb, :provider_id]]
33
-
34
- record.involved = build_bookmark
35
- record.actor = build_actor
36
-
37
- record
29
+ actions.compact
38
30
  end
39
31
 
40
- def build_bookmark
41
- record = ::Chronicle::ETL::Models::Entity.new
42
- record.title = @bookmark[:description]
43
- record.provider_url = @bookmark[:href]
44
- record.dedupe_on << [:provider_url]
32
+ private
45
33
 
46
- record.abouts = build_tags
34
+ def build_bookmark(site:, agent:, id:, end_time:)
35
+ Chronicle::Models::BookmarkAction.new do |r|
36
+ r.source = 'pinboard'
37
+ r.source_id = id
38
+ r.end_time = end_time
39
+ r.agent = agent
40
+ r.object = site
47
41
 
48
- record.aboutables = build_note
49
- record
42
+ r.dedupe_on = [%i[source source_id type]]
43
+ end
50
44
  end
51
45
 
52
- def build_note
53
- note = @bookmark[:extended]
54
- return unless note.size.positive?
55
-
56
- record = ::Chronicle::ETL::Models::Entity.new
57
- record.provider_id = id
58
- record.represents = "thought"
59
- record.body = note
60
- record.provider = "pinboard"
61
- record.dedupe_on << [:represents, :provider, :provider_id]
62
-
63
- involvement = ::Chronicle::ETL::Models::Activity.new
64
- involvement.end_at = timestamp
65
- involvement.verb = 'noted'
66
- involvement.provider_id = id
67
- involvement.provider = 'pinboard'
68
- involvement.dedupe_on << [:provider, :verb, :provider_id]
69
- involvement.actor = build_actor
46
+ def build_comment(site:, agent:, id:, note:, end_time:)
47
+ comment = Chronicle::Models::Comment.new do |r|
48
+ r.source = 'pinboard'
49
+ r.source_id = id
50
+ r.text = note
51
+ r.about = [site]
52
+ r.dedupe_on = [%i[source source_id type]]
53
+ end
70
54
 
71
- record.involvements = [involvement]
55
+ Chronicle::Models::CommentAction.new do |r|
56
+ r.source = 'pinboard'
57
+ r.source_id = id
58
+ r.end_time = end_time
59
+ r.agent = agent
60
+ r.result = comment
61
+ r.object = site
72
62
 
73
- record
63
+ r.dedupe_on = [%i[source source_id type]]
64
+ end
74
65
  end
75
66
 
76
- def build_tags
77
- @bookmark[:tags].split(" ").map do |tag|
78
- record = ::Chronicle::ETL::Models::Entity.new
79
- record.represents = 'topic'
80
- record.provider = 'pinboard'
81
- record.slug = tag.downcase
82
- record.dedupe_on << [:provider, :slug, :represents]
83
- record
67
+ def build_site(bookmark)
68
+ Chronicle::Models::Thing.new do |r|
69
+ r.name = bookmark[:description]
70
+ r.url = bookmark[:href]
71
+ r.dedupe_on = [[:url]]
72
+ r.keywords = bookmark[:tags].split.map(&:strip)
84
73
  end
85
74
  end
86
75
 
87
- def build_actor
88
- record = ::Chronicle::ETL::Models::Entity.new
89
- record.represents = 'identity'
90
- record.slug = @extraction.meta[:username]
91
- record.provider = 'pinboard'
92
- record.provider_url = "https://pinboard.in/u:#{record.slug}"
93
- record.dedupe_on << [:provider_url]
94
- record.dedupe_on << [:provider, :represents, :slug]
95
- record
76
+ def build_agent(username)
77
+ Chronicle::Models::Person.new do |r|
78
+ r.source = 'pinboard'
79
+ r.slug = username
80
+ r.url = "https://pinboard.in/u:#{username}"
81
+ r.dedupe_on = [[:url], %i[source slug type]]
82
+ end
96
83
  end
97
84
  end
98
85
  end
@@ -1,7 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Chronicle
4
2
  module Pinboard
5
- VERSION = "0.1.1"
3
+ VERSION = '0.2.0'
6
4
  end
7
5
  end
@@ -1,8 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "pinboard/version"
4
- require_relative "pinboard/pinboard_extractor"
5
- require_relative "pinboard/pinboard_transformer"
1
+ require_relative 'pinboard/version'
2
+ require_relative 'pinboard/pinboard_extractor'
3
+ require_relative 'pinboard/pinboard_transformer'
6
4
 
7
5
  module Chronicle
8
6
  module Pinboard
metadata CHANGED
@@ -1,43 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronicle-pinboard
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-30 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'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '0.5'
40
+ version: '0.6'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: faraday
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '2.2'
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'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.4'
34
76
  type: :runtime
35
77
  prerelease: false
36
78
  version_requirements: !ruby/object:Gem::Requirement
37
79
  requirements:
38
80
  - - "~>"
39
81
  - !ruby/object:Gem::Version
40
- version: '2.2'
82
+ version: '1.4'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: bundler
43
85
  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 Pinboard bookmarks
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
@@ -106,6 +163,7 @@ metadata:
106
163
  homepage_uri: https://github.com/chronicle-app/chronicle-pinboard
107
164
  source_code_uri: https://github.com/chronicle-app/chronicle-pinboard
108
165
  changelog_uri: https://github.com/chronicle-app/chronicle-pinboard
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: Pinboard importer for Chronicle