hatenablog 0.7.0 → 0.8.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/.github/workflows/build.yml +38 -21
- data/.gitignore +1 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +5 -1
- data/README.md +17 -9
- data/Rakefile +1 -0
- data/Steepfile +11 -0
- data/exe/{get_access_token → get_hatena_oauth_access_token} +0 -0
- data/hatenablog.gemspec +1 -1
- data/lib/hatenablog/category.rb +3 -2
- data/lib/hatenablog/client.rb +34 -7
- data/lib/hatenablog/configuration.rb +2 -0
- data/lib/hatenablog/entry.rb +12 -3
- data/lib/hatenablog/feed.rb +2 -1
- data/lib/hatenablog/requester.rb +12 -7
- data/lib/hatenablog/version.rb +1 -1
- data/rbs_collection.lock.yaml +36 -0
- data/rbs_collection.yaml +36 -0
- data/sig/hatenablog.rbs +249 -0
- metadata +14 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c6ebd627cfd566a53f9423b632b3ef6f42d285e2ffa84b176af438022a78bbe
|
4
|
+
data.tar.gz: c7dbd064aee0d3557c17464be93b351cc741b973c16ede5dd6d8cf6afde30bfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe094c01e6c51c1b41bd674bc6aa891767532c3472135312709d090bd1301dfcc3041fb95e90a7a641c20ea07f5a32403d6d006a13a8a6c16aa319c74ad1c454
|
7
|
+
data.tar.gz: 8c86b99f15106170419012c8e8d15c90b1a2644488a62b16cfb76defad288ca81cb04a920f772d8fedf314f88ff8c4351889439a766e59305caad5134d0d15cf
|
data/.github/workflows/build.yml
CHANGED
@@ -1,32 +1,49 @@
|
|
1
1
|
name: build
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
4
8
|
|
5
9
|
jobs:
|
6
10
|
build:
|
7
11
|
runs-on: ubuntu-latest
|
8
12
|
strategy:
|
9
13
|
matrix:
|
10
|
-
ruby: ['2.
|
14
|
+
ruby: ['2.6', '2.7', '3.0', '3.1.0-preview1']
|
11
15
|
include:
|
12
|
-
- ruby: '
|
16
|
+
- ruby: '3.0'
|
13
17
|
report-coverage: true
|
14
18
|
steps:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- run: gem install bundler
|
24
|
+
- run: bundle install -j4
|
25
|
+
- name: Run tests and report test coverage
|
26
|
+
if: matrix.report-coverage
|
27
|
+
uses: paambaati/codeclimate-action@v2.7.5
|
28
|
+
env:
|
29
|
+
CC_TEST_REPORTER_ID: 309cf0784d00d2a6009566d28be111a8a0280cdeb2da280225eedf577b16beb5
|
30
|
+
with:
|
31
|
+
coverageCommand: bundle exec rake
|
32
|
+
coverageLocations: ${{github.workspace}}/coverage/coverage.json:simplecov
|
33
|
+
- name: Run tests
|
34
|
+
if: "!matrix.report-coverage"
|
35
|
+
env:
|
36
|
+
TZ: Asia/Tokyo
|
37
|
+
run: bundle exec rake
|
38
|
+
steep:
|
39
|
+
runs-on: ubuntu-latest
|
40
|
+
steps:
|
41
|
+
- uses: actions/checkout@v2
|
42
|
+
with:
|
43
|
+
submodules: 'true'
|
44
|
+
- uses: ruby/setup-ruby@v1
|
45
|
+
with:
|
46
|
+
ruby-version: '3.0'
|
47
|
+
- run: bundle install -j4
|
48
|
+
- run: rbs collection install
|
49
|
+
- run: bundle exec steep check
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## Unreleased
|
8
|
+
|
9
|
+
## 0.8.0 - 2021-11-20
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- [Create the signature with RBS](https://github.com/kymmt90/hatenablog/pull/24)
|
14
|
+
- This is experimental
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- [Change the executable name to more specific one](https://github.com/kymmt90/hatenablog/pull/26)
|
19
|
+
- From `get_access_token` to `get_hatena_oauth_access_token`
|
20
|
+
- [Use only supported Rubies in 2021-11](https://github.com/kymmt90/hatenablog/pull/27)
|
21
|
+
- Drop Ruby 2.4 and 2.5 and add Ruby 3.1.0-preview1
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -19,15 +19,21 @@ This gem supports following operations through OAuth 1.0a or Basic authenticatio
|
|
19
19
|
|
20
20
|
Add this line to your application's Gemfile:
|
21
21
|
|
22
|
-
|
22
|
+
```
|
23
|
+
gem 'hatenablog'
|
24
|
+
```
|
23
25
|
|
24
26
|
And then execute:
|
25
27
|
|
26
|
-
|
28
|
+
```
|
29
|
+
$ bundle
|
30
|
+
```
|
27
31
|
|
28
32
|
Or install it yourself as:
|
29
33
|
|
30
|
-
|
34
|
+
```
|
35
|
+
$ gem install hatenablog
|
36
|
+
```
|
31
37
|
|
32
38
|
### Get OAuth credentials
|
33
39
|
|
@@ -41,11 +47,13 @@ Access [Hatena application registoration page](http://developer.hatena.ne.jp/) a
|
|
41
47
|
|
42
48
|
Execute this command:
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
```
|
51
|
+
$ get_hatena_oauth_access_token <your consumer key> <your consumer secret>
|
52
|
+
Visit this website and get the PIN: https://www.hatena.com/oauth/authorize?oauth_token=XXXXXXXXXXXXXXXXXXXX
|
53
|
+
Enter the PIN: <your PIN> [Enter]
|
54
|
+
Access token: <your access token>
|
55
|
+
Access token secret: <your access token secret>
|
56
|
+
```
|
49
57
|
|
50
58
|
#### 3. [Optional] Set up the YAML configuration file
|
51
59
|
|
@@ -164,7 +172,7 @@ feed.uri
|
|
164
172
|
feed.next_uri # The next feed URI
|
165
173
|
feed.title
|
166
174
|
feed.author_name
|
167
|
-
feed.
|
175
|
+
feed.updated # Updated datetime
|
168
176
|
|
169
177
|
feed.entries # entries in the feed
|
170
178
|
feed.each_entry do |entry|
|
data/Rakefile
CHANGED
data/Steepfile
ADDED
File without changes
|
data/hatenablog.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.required_ruby_version = '>= 2.
|
22
|
+
spec.required_ruby_version = '>= 2.3'
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler"
|
25
25
|
spec.add_development_dependency "rake"
|
data/lib/hatenablog/category.rb
CHANGED
@@ -16,9 +16,10 @@ module Hatenablog
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def each(&block)
|
19
|
-
return enum_for
|
19
|
+
return enum_for unless block_given?
|
20
20
|
|
21
21
|
@categories.each do |category|
|
22
|
+
# @type var block: ^(String) -> void
|
22
23
|
block.call(category)
|
23
24
|
end
|
24
25
|
end
|
@@ -38,7 +39,7 @@ module Hatenablog
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def parse_document
|
41
|
-
@categories = @document.css('atom|category').inject(
|
42
|
+
@categories = @document.css('atom|category').inject(Array.new) do |categories, category|
|
42
43
|
categories << category['term'].to_s
|
43
44
|
end
|
44
45
|
|
data/lib/hatenablog/client.rb
CHANGED
@@ -12,6 +12,7 @@ module Hatenablog
|
|
12
12
|
MEMBER_URI = "https://blog.hatena.ne.jp/%s/%s/atom/entry/%s".freeze
|
13
13
|
CATEGORY_URI = "https://blog.hatena.ne.jp/%s/%s/atom/category".freeze
|
14
14
|
|
15
|
+
# @dynamic requester=
|
15
16
|
attr_writer :requester
|
16
17
|
|
17
18
|
# Create a new hatenablog AtomPub client from a configuration file.
|
@@ -24,9 +25,9 @@ module Hatenablog
|
|
24
25
|
yield blog
|
25
26
|
end
|
26
27
|
|
27
|
-
def initialize(config =
|
28
|
+
def initialize(config = Configuration.new)
|
28
29
|
if block_given?
|
29
|
-
yield config
|
30
|
+
yield config
|
30
31
|
config.check_valid_or_raise
|
31
32
|
end
|
32
33
|
@requester = Requester.create(config)
|
@@ -59,7 +60,7 @@ module Hatenablog
|
|
59
60
|
# Get all blog entries.
|
60
61
|
# @return [Hatenablog::Entries] enumerator of blog entries
|
61
62
|
def all_entries
|
62
|
-
Entries.new(self,
|
63
|
+
Entries.new(self, 0, :all)
|
63
64
|
end
|
64
65
|
|
65
66
|
# Get the next feed of the given feed.
|
@@ -161,7 +162,7 @@ module Hatenablog
|
|
161
162
|
xml.name author_name
|
162
163
|
end
|
163
164
|
xml.content(content, type: 'text/x-markdown')
|
164
|
-
xml.updated updated
|
165
|
+
xml.updated updated if updated && !updated.empty?
|
165
166
|
categories.each do |category|
|
166
167
|
xml.category(term: category)
|
167
168
|
end
|
@@ -207,19 +208,45 @@ module Hatenablog
|
|
207
208
|
class Entries
|
208
209
|
include Enumerable
|
209
210
|
|
210
|
-
def initialize(client, page = 0)
|
211
|
+
def initialize(client, page = 0, fetch = :partial)
|
211
212
|
@client = client
|
212
213
|
@page = page
|
214
|
+
@fetch = fetch
|
213
215
|
end
|
214
216
|
|
215
217
|
def each(&block)
|
216
|
-
return enum_for
|
218
|
+
return enum_for unless block_given?
|
219
|
+
|
220
|
+
# @type var block: ^(Entry) -> void
|
221
|
+
if @fetch == :all
|
222
|
+
each_all(&block)
|
223
|
+
else
|
224
|
+
each_partial(&block)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
private
|
229
|
+
|
230
|
+
def each_all(&block)
|
231
|
+
feed = nil
|
232
|
+
|
233
|
+
while feed = @client.next_feed(feed)
|
234
|
+
feed.entries.each { |entry| block.call(entry) }
|
235
|
+
end
|
236
|
+
|
237
|
+
self
|
238
|
+
end
|
239
|
+
|
240
|
+
def each_partial(&block)
|
241
|
+
feed = nil
|
217
242
|
|
218
243
|
current_page = 0
|
219
|
-
|
244
|
+
while current_page <= @page && feed = @client.next_feed(feed)
|
220
245
|
feed.entries.each { |entry| block.call(entry) }
|
221
246
|
current_page += 1
|
222
247
|
end
|
248
|
+
|
249
|
+
self
|
223
250
|
end
|
224
251
|
end
|
225
252
|
end
|
@@ -4,6 +4,8 @@ require 'ostruct'
|
|
4
4
|
|
5
5
|
module Hatenablog
|
6
6
|
class Configuration < OpenStruct
|
7
|
+
# @dynamic auth_type, consumer_key, consumer_secret, access_token, access_token_secret, api_key, user_id, blog_id
|
8
|
+
|
7
9
|
OAUTH_KEYS = %i(consumer_key consumer_secret access_token access_token_secret user_id blog_id)
|
8
10
|
BASIC_KEYS = %i(api_key user_id blog_id)
|
9
11
|
|
data/lib/hatenablog/entry.rb
CHANGED
@@ -3,6 +3,9 @@ require 'time'
|
|
3
3
|
|
4
4
|
module Hatenablog
|
5
5
|
module AfterHook
|
6
|
+
# @dynamic uri=, edit_uri=, author_name=, title=, content=, updated=, draft=, categories=
|
7
|
+
# @dynamic instance_methods, alias_method, define_method
|
8
|
+
|
6
9
|
# Register a hooking method for given methods.
|
7
10
|
# The hook method is executed after calling given methods.
|
8
11
|
# @param [Symbol] hooking method name
|
@@ -17,6 +20,7 @@ module Hatenablog
|
|
17
20
|
alias_method origin_method, method
|
18
21
|
|
19
22
|
define_method(method) do |*args, &block|
|
23
|
+
# @type var block: ^(*untyped) -> untyped
|
20
24
|
result = send(origin_method, *args, &block)
|
21
25
|
send(hook)
|
22
26
|
result
|
@@ -28,8 +32,13 @@ module Hatenablog
|
|
28
32
|
class Entry
|
29
33
|
extend AfterHook
|
30
34
|
|
35
|
+
# @dynamic uri, uri=, author_name, author_name=, title, title=, content, content=, draft, draft=
|
31
36
|
attr_accessor :uri, :author_name, :title, :content, :draft
|
32
|
-
|
37
|
+
|
38
|
+
# @dynamic edit_uri, id, updated
|
39
|
+
attr_reader :edit_uri, :id, :updated
|
40
|
+
|
41
|
+
# @dynamic categories=
|
33
42
|
attr_writer :categories
|
34
43
|
|
35
44
|
def updated=(date)
|
@@ -147,7 +156,7 @@ module Hatenablog
|
|
147
156
|
end
|
148
157
|
|
149
158
|
def parse_categories
|
150
|
-
categories = @document.css('category').inject(
|
159
|
+
categories = @document.css('category').inject(Array.new) do |categories, category|
|
151
160
|
categories << category['term'].to_s
|
152
161
|
end
|
153
162
|
categories
|
@@ -162,7 +171,7 @@ module Hatenablog
|
|
162
171
|
@document.at_css('entry app|control app|draft').content = @draft
|
163
172
|
|
164
173
|
unless @updated.nil? || @document.at_css('entry updated').nil?
|
165
|
-
@document.at_css('entry updated').content = @updated
|
174
|
+
@document.at_css('entry updated').content = @updated&.iso8601
|
166
175
|
end
|
167
176
|
|
168
177
|
unless @categories.nil?
|
data/lib/hatenablog/feed.rb
CHANGED
@@ -5,6 +5,7 @@ require 'hatenablog/entry'
|
|
5
5
|
|
6
6
|
module Hatenablog
|
7
7
|
class Feed
|
8
|
+
# @dynamic uri, next_uri, title, author_name, updated
|
8
9
|
attr_reader :uri, :next_uri, :title, :author_name, :updated
|
9
10
|
|
10
11
|
# Create a new blog feed from a XML string.
|
@@ -53,7 +54,7 @@ module Hatenablog
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def parse_entry
|
56
|
-
@entries = @document.css('feed > entry').inject(
|
57
|
+
@entries = @document.css('feed > entry').inject(Array.new) do |entries, entry|
|
57
58
|
# add namespace 'app' to recognize XML correctly
|
58
59
|
entry['xmlns:app'] = 'http://www.w3.org/2007/app'
|
59
60
|
entries << Hatenablog::Entry.load_xml(entry.to_s)
|
data/lib/hatenablog/requester.rb
CHANGED
@@ -96,7 +96,7 @@ module Hatenablog
|
|
96
96
|
# @param [string] body HTTP request body
|
97
97
|
# @param [string] headers HTTP request headers
|
98
98
|
# @return [Net::HTTPResponse] HTTP response
|
99
|
-
def post(uri, body, headers =
|
99
|
+
def post(uri, body, headers = {})
|
100
100
|
request(uri, :post, body: body, headers: headers)
|
101
101
|
end
|
102
102
|
|
@@ -105,7 +105,7 @@ module Hatenablog
|
|
105
105
|
# @param [string] body HTTP request body
|
106
106
|
# @param [string] headers HTTP request headers
|
107
107
|
# @return [Net::HTTPResponse] HTTP response
|
108
|
-
def put(uri, body, headers =
|
108
|
+
def put(uri, body, headers = {})
|
109
109
|
request(uri, :put, body: body, headers: headers)
|
110
110
|
end
|
111
111
|
|
@@ -113,22 +113,27 @@ module Hatenablog
|
|
113
113
|
# @param [string] uri target URI
|
114
114
|
# @param [string] headers HTTP request headers
|
115
115
|
# @return [Net::HTTPResponse] HTTP response
|
116
|
-
def delete(uri, headers =
|
116
|
+
def delete(uri, headers = {})
|
117
117
|
request(uri, :delete, headers: headers)
|
118
118
|
end
|
119
119
|
|
120
120
|
private
|
121
|
-
|
121
|
+
|
122
|
+
def request(uri, method, body: nil, headers: {})
|
122
123
|
uri = URI(uri)
|
123
|
-
req = METHODS[method].new(uri, headers)
|
124
|
+
req = METHODS[method].new(uri.to_s, headers)
|
124
125
|
req.basic_auth @user_id, @api_key
|
125
126
|
if body
|
126
127
|
req.body = body
|
127
128
|
req.content_type = ATOM_CONTENT_TYPE
|
128
129
|
end
|
129
130
|
|
130
|
-
http = Net::HTTP.
|
131
|
-
http.
|
131
|
+
http = Net::HTTP.new(uri.hostname, uri.port)
|
132
|
+
http.use_ssl = uri.port == 443
|
133
|
+
http.start do |conn|
|
134
|
+
conn.request(req)
|
135
|
+
end
|
136
|
+
|
132
137
|
rescue => problem
|
133
138
|
raise RequestError, "Fail to #{method.upcase}: " + problem.to_s
|
134
139
|
end
|
data/lib/hatenablog/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
sources:
|
3
|
+
- name: ruby/gem_rbs_collection
|
4
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
5
|
+
revision: main
|
6
|
+
repo_dir: gems
|
7
|
+
path: ".gem_rbs_collection"
|
8
|
+
gems:
|
9
|
+
- name: erb
|
10
|
+
version: '0'
|
11
|
+
source:
|
12
|
+
type: stdlib
|
13
|
+
- name: net-http
|
14
|
+
version: '0'
|
15
|
+
source:
|
16
|
+
type: stdlib
|
17
|
+
- name: set
|
18
|
+
version: '0'
|
19
|
+
source:
|
20
|
+
type: stdlib
|
21
|
+
- name: time
|
22
|
+
version: '0'
|
23
|
+
source:
|
24
|
+
type: stdlib
|
25
|
+
- name: uri
|
26
|
+
version: '0'
|
27
|
+
source:
|
28
|
+
type: stdlib
|
29
|
+
- name: nokogiri
|
30
|
+
version: '1.11'
|
31
|
+
source:
|
32
|
+
type: git
|
33
|
+
name: ruby/gem_rbs_collection
|
34
|
+
revision: 88e86e0b67262f9ab6244a356e81dd9ca8c55b37
|
35
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
36
|
+
repo_dir: gems
|
data/rbs_collection.yaml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Download sources
|
2
|
+
sources:
|
3
|
+
- name: ruby/gem_rbs_collection
|
4
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
5
|
+
revision: main
|
6
|
+
repo_dir: gems
|
7
|
+
|
8
|
+
# A directory to install the downloaded RBSs
|
9
|
+
path: .gem_rbs_collection
|
10
|
+
|
11
|
+
gems:
|
12
|
+
# stdlibs
|
13
|
+
- name: erb
|
14
|
+
- name: net-http
|
15
|
+
- name: set
|
16
|
+
- name: time
|
17
|
+
- name: uri
|
18
|
+
|
19
|
+
# gems
|
20
|
+
- name: nokogiri
|
21
|
+
|
22
|
+
# not used
|
23
|
+
- name: activesupport
|
24
|
+
ignore: true
|
25
|
+
- name: ast
|
26
|
+
ignore: true
|
27
|
+
- name: listen
|
28
|
+
ignore: true
|
29
|
+
- name: parallel
|
30
|
+
ignore: true
|
31
|
+
- name: rainbow
|
32
|
+
ignore: true
|
33
|
+
- name: rbs
|
34
|
+
ignore: true
|
35
|
+
- name: steep
|
36
|
+
ignore: true
|
data/sig/hatenablog.rbs
ADDED
@@ -0,0 +1,249 @@
|
|
1
|
+
module Hatenablog
|
2
|
+
VERSION: String
|
3
|
+
|
4
|
+
class Category
|
5
|
+
@document: Nokogiri::XML::Document
|
6
|
+
@categories: Array[String]
|
7
|
+
@fixed: String
|
8
|
+
|
9
|
+
def self.load_xml: (String xml) -> Category
|
10
|
+
|
11
|
+
def categories: () -> Array[String]
|
12
|
+
def each: () -> Enumerator[untyped, self]
|
13
|
+
| () { (String) -> void } -> Array[String]
|
14
|
+
def fixed?: () -> bool
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def initialize: (String xml) -> void
|
19
|
+
def parse_document: () -> void
|
20
|
+
end
|
21
|
+
|
22
|
+
class Client
|
23
|
+
DEFAULT_CONFIG_PATH: String
|
24
|
+
COLLECTION_URI: String
|
25
|
+
MEMBER_URI: String
|
26
|
+
CATEGORY_URI: String
|
27
|
+
|
28
|
+
@user_id: String
|
29
|
+
@blog_id: String
|
30
|
+
|
31
|
+
attr_writer requester: Requester::Basic | Requester::OAuth
|
32
|
+
|
33
|
+
def self.create: (?String config_file) -> Client
|
34
|
+
| (?String config_file) { (Client) -> void } -> void
|
35
|
+
|
36
|
+
def initialize: (?Configuration config) ?{ (Configuration) -> void } -> void
|
37
|
+
def title: () -> String
|
38
|
+
def author_name: () -> String
|
39
|
+
def entries: (?Integer page) -> Entries
|
40
|
+
def all_entries: () -> Entries
|
41
|
+
def next_feed: (?Feed? feed) -> Feed?
|
42
|
+
def categories: () -> Array[String]
|
43
|
+
def get_entry: (String entry_id) -> Entry
|
44
|
+
def post_entry: (?String title, ?String content, ?Array[String] categories, ?String draft) -> Entry
|
45
|
+
def update_entry: (String entry_id, ?String title, ?String content, ?Array[String] categories, ?String draft, ?String updated) -> Entry
|
46
|
+
def delete_entry: (String entry_id) -> void
|
47
|
+
def collection_uri: (?String user_id, ?String blog_id) -> String
|
48
|
+
def member_uri: (String entry_id, ?String user_id, ?String blog_id) -> String
|
49
|
+
def category_doc_uri: (?String user_id, ?String blog_id) -> String
|
50
|
+
def entry_xml: (?String title, ?String content, ?Array[String] categories, ?String draft, ?String updated, ?String author_name) -> String
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def get: (String uri) -> Net::HTTPResponse
|
55
|
+
def get_collection: (?String uri) -> Net::HTTPResponse
|
56
|
+
def get_category_doc: () -> Net::HTTPResponse
|
57
|
+
def post: (String entry_xml, ?String uri) -> Net::HTTPResponse
|
58
|
+
def put: (String entry_xml, String uri) -> Net::HTTPResponse
|
59
|
+
def delete: (String uri) -> Net::HTTPResponse
|
60
|
+
end
|
61
|
+
|
62
|
+
class Entries
|
63
|
+
include Enumerable[Entry]
|
64
|
+
|
65
|
+
@client: Client
|
66
|
+
@page: Integer
|
67
|
+
@fetch: :partial | :all
|
68
|
+
|
69
|
+
def initialize: (Client client, ?Integer page, ?(:partial | :all) fetch) -> void
|
70
|
+
def each: () -> Enumerator[untyped, self]
|
71
|
+
| () { (Entry) -> void } -> Entries
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def each_all: () { (Entry) -> void } -> Entries
|
76
|
+
def each_partial: () { (Entry) -> void } -> Entries
|
77
|
+
end
|
78
|
+
|
79
|
+
class Configuration < OpenStruct
|
80
|
+
OAUTH_KEYS: [:consumer_key, :consumer_secret, :access_token, :access_token_secret, :user_id, :blog_id]
|
81
|
+
BASIC_KEYS: [:api_key, :user_id, :blog_id]
|
82
|
+
|
83
|
+
def self.create: (String) -> Configuration
|
84
|
+
def check_valid_or_raise: () -> Configuration
|
85
|
+
|
86
|
+
# attribute accessors allowed to define dynamically
|
87
|
+
def consumer_key: () -> untyped # String?
|
88
|
+
def consumer_secret: () -> untyped # String?
|
89
|
+
def access_token: () -> untyped # String?
|
90
|
+
def access_token_secret: () -> untyped # String?
|
91
|
+
def user_id: () -> String
|
92
|
+
def blog_id: () -> String
|
93
|
+
def api_key: () -> untyped # String?
|
94
|
+
def auth_type: () -> untyped # String?
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def lacking_keys: () -> (Array[:consumer_key | :consumer_secret | :access_token | :access_token_secret | :user_id | :blog_id | :api_key | :user_id | :blog_id])
|
99
|
+
end
|
100
|
+
|
101
|
+
class ConfigurationError < StandardError
|
102
|
+
end
|
103
|
+
|
104
|
+
module AfterHook
|
105
|
+
def after_hook: (Symbol hook, *Symbol methods) -> Array[Symbol]
|
106
|
+
|
107
|
+
# methods hooked dynamically
|
108
|
+
def uri=: (String uri) -> untyped
|
109
|
+
def edit_uri=: (String uri) -> untyped
|
110
|
+
def author_name=: (String author_name) -> untyped
|
111
|
+
def title=: (String title) -> untyped
|
112
|
+
def content=: (String content) -> untyped
|
113
|
+
def updated=: (String date) -> untyped
|
114
|
+
def draft=: (String draft) -> untyped
|
115
|
+
def categories=: (Array[String] categories) -> untyped
|
116
|
+
|
117
|
+
# workaround for using `Module` instance methods in `after_hook`
|
118
|
+
def alias_method: (::Symbol | ::String new_name, ::Symbol | ::String old_name) -> ::Symbol
|
119
|
+
def define_method: (Symbol | String arg0, ?Proc | Method | UnboundMethod arg1) -> Symbol
|
120
|
+
| (Symbol | String arg0) { () -> untyped } -> Symbol
|
121
|
+
def instance_methods: (?boolish include_super) -> ::Array[Symbol]
|
122
|
+
end
|
123
|
+
|
124
|
+
class Entry
|
125
|
+
extend AfterHook
|
126
|
+
|
127
|
+
@document: Nokogiri::XML::Document
|
128
|
+
@formatted_content: untyped
|
129
|
+
|
130
|
+
attr_accessor uri: String
|
131
|
+
attr_accessor author_name: String
|
132
|
+
attr_accessor title: String
|
133
|
+
attr_accessor content: String
|
134
|
+
attr_accessor draft: String
|
135
|
+
|
136
|
+
attr_reader edit_uri: String
|
137
|
+
attr_reader id: String?
|
138
|
+
attr_reader updated : Time?
|
139
|
+
|
140
|
+
attr_writer categories: Array[String]
|
141
|
+
|
142
|
+
def self.load_xml: (String xml) -> Entry
|
143
|
+
def self.create: (?uri: String, ?edit_uri: String, ?author_name: String, ?title: String, ?content: String, ?draft: String, ?categories: Array[String], ?updated: String) ?{ (Entry) -> void } -> Entry
|
144
|
+
def self.build_xml: (String uri, String edit_uri, String author_name, String title, String content, String draft, Array[String]? categories, String? updated) -> String
|
145
|
+
|
146
|
+
def updated=: (String date) -> Time?
|
147
|
+
def edit_uri=: (String uri) -> void
|
148
|
+
def draft?: () -> bool
|
149
|
+
def categories: () -> Array[String]
|
150
|
+
def each_category: () { (String) -> void } -> Array[String]
|
151
|
+
def to_xml: () -> String
|
152
|
+
def formatted_content: () -> untyped # result of Nokogiri::XML::NodeSet#[]
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def initialize: (String xml) -> void
|
157
|
+
def parse_document: () -> void
|
158
|
+
def parse_categories: () -> Array[untyped]
|
159
|
+
def update_xml: () -> void
|
160
|
+
def categories_modified?: (Nokogiri::XML::NodeSet old_categories, Array[String] new_categories) -> bool
|
161
|
+
end
|
162
|
+
|
163
|
+
class Feed
|
164
|
+
@document: Nokogiri::XML::Document
|
165
|
+
@entries: Array[Entry]
|
166
|
+
|
167
|
+
attr_reader uri: String
|
168
|
+
attr_reader next_uri: String
|
169
|
+
attr_reader title: String
|
170
|
+
attr_reader author_name: String
|
171
|
+
attr_reader updated: Time
|
172
|
+
|
173
|
+
def self.load_xml: (String xml) -> Feed
|
174
|
+
|
175
|
+
def entries: () -> Array[Entry]
|
176
|
+
def each_entry: () { (Entry) -> void } -> Array[Entry]
|
177
|
+
def has_next?: () -> bool
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def initialize: (String xml) -> void
|
182
|
+
def parse_document: () -> void
|
183
|
+
def parse_entry: () -> void
|
184
|
+
end
|
185
|
+
|
186
|
+
module Requester
|
187
|
+
ATOM_CONTENT_TYPE: String
|
188
|
+
DEFAULT_HEADER: Hash[String, String]
|
189
|
+
|
190
|
+
def self.create: (Configuration config) -> (Basic | OAuth)
|
191
|
+
|
192
|
+
class RequestError < StandardError
|
193
|
+
end
|
194
|
+
|
195
|
+
class OAuth
|
196
|
+
@access_token: ::OAuth::AccessToken
|
197
|
+
|
198
|
+
def initialize: (::OAuth::AccessToken access_token) -> void
|
199
|
+
def get: (String uri) -> Net::HTTPResponse
|
200
|
+
def post: (String uri, ?String body, ?Hash[String, String] headers) -> Net::HTTPResponse
|
201
|
+
def put: (String uri, ?String body, ?Hash[String, String] headers) -> Net::HTTPResponse
|
202
|
+
def delete: (String uri, ?Hash[String, String] headers) -> Net::HTTPResponse
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def request: (:get | :post | :put | :delete method, String uri, ?body: String?, ?headers: Hash[String, String]?) -> Net::HTTPResponse
|
207
|
+
end
|
208
|
+
|
209
|
+
class Basic
|
210
|
+
METHODS: {get: singleton(Net::HTTP::Get), post: singleton(Net::HTTP::Post), put: singleton(Net::HTTP::Put), delete: singleton(Net::HTTP::Delete)}
|
211
|
+
|
212
|
+
@user_id: String
|
213
|
+
@api_key: String
|
214
|
+
|
215
|
+
def initialize: (String user_id, String api_key) -> void
|
216
|
+
def get: (String uri) -> Net::HTTPResponse
|
217
|
+
def post: (String uri, String body, ?Hash[String, String] headers) -> Net::HTTPResponse
|
218
|
+
def put: (String uri, String body, ?Hash[String, String] headers) -> Net::HTTPResponse
|
219
|
+
def delete: (String uri, ?Hash[String, String] headers) -> Net::HTTPResponse
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
def request: (String uri, :get | :post | :put | :delete method, ?body: String?, ?headers: Hash[String, String]) -> Net::HTTPResponse
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# polyfill for ostruct
|
229
|
+
class OpenStruct
|
230
|
+
def initialize: (?Hash[untyped, untyped]? hash) -> OpenStruct
|
231
|
+
def []: (String | Symbol) -> Object
|
232
|
+
def to_h: -> Hash[Symbol, Object]
|
233
|
+
end
|
234
|
+
|
235
|
+
# polyfill for oauth
|
236
|
+
module OAuth
|
237
|
+
class AccessToken
|
238
|
+
def initialize: (untyped, untyped, ?untyped) -> void
|
239
|
+
end
|
240
|
+
|
241
|
+
class Consumer
|
242
|
+
def initialize: (untyped, untyped, ?untyped) -> void
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# polyfill for yaml
|
247
|
+
module YAML
|
248
|
+
def self.load: (String yaml, ?String? filename, ?fallback: bool, ?symbolize_names: bool) -> untyped
|
249
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hatenablog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kohei Yamamoto
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -126,19 +126,21 @@ description: Hatenablog AtomPub API library
|
|
126
126
|
email:
|
127
127
|
- kymmt90@gmail.com
|
128
128
|
executables:
|
129
|
-
-
|
129
|
+
- get_hatena_oauth_access_token
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
133
|
- ".github/workflows/build.yml"
|
134
134
|
- ".gitignore"
|
135
|
+
- CHANGELOG.md
|
135
136
|
- Gemfile
|
136
137
|
- LICENSE.txt
|
137
138
|
- README.md
|
138
139
|
- Rakefile
|
140
|
+
- Steepfile
|
139
141
|
- bin/console
|
140
142
|
- bin/setup
|
141
|
-
- exe/
|
143
|
+
- exe/get_hatena_oauth_access_token
|
142
144
|
- hatenablog.gemspec
|
143
145
|
- lib/hatenablog.rb
|
144
146
|
- lib/hatenablog/category.rb
|
@@ -148,11 +150,14 @@ files:
|
|
148
150
|
- lib/hatenablog/feed.rb
|
149
151
|
- lib/hatenablog/requester.rb
|
150
152
|
- lib/hatenablog/version.rb
|
153
|
+
- rbs_collection.lock.yaml
|
154
|
+
- rbs_collection.yaml
|
155
|
+
- sig/hatenablog.rbs
|
151
156
|
homepage: https://github.com/kymmt90/hatenablog
|
152
157
|
licenses:
|
153
158
|
- MIT
|
154
159
|
metadata: {}
|
155
|
-
post_install_message:
|
160
|
+
post_install_message:
|
156
161
|
rdoc_options: []
|
157
162
|
require_paths:
|
158
163
|
- lib
|
@@ -160,15 +165,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
165
|
requirements:
|
161
166
|
- - ">="
|
162
167
|
- !ruby/object:Gem::Version
|
163
|
-
version: '2.
|
168
|
+
version: '2.3'
|
164
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
170
|
requirements:
|
166
171
|
- - ">="
|
167
172
|
- !ruby/object:Gem::Version
|
168
173
|
version: '0'
|
169
174
|
requirements: []
|
170
|
-
rubygems_version: 3.
|
171
|
-
signing_key:
|
175
|
+
rubygems_version: 3.2.3
|
176
|
+
signing_key:
|
172
177
|
specification_version: 4
|
173
178
|
summary: Hatenablog AtomPub API library
|
174
179
|
test_files: []
|