skyfall 0.2.5 → 0.3.1
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/CHANGELOG.md +20 -0
- data/README.md +4 -1
- data/lib/skyfall/collection.rb +15 -12
- data/lib/skyfall/label.rb +63 -0
- data/lib/skyfall/messages/account_message.rb +11 -0
- data/lib/skyfall/messages/handle_message.rb +5 -0
- data/lib/skyfall/messages/identity_message.rb +3 -0
- data/lib/skyfall/messages/labels_message.rb +23 -0
- data/lib/skyfall/messages/tombstone_message.rb +5 -0
- data/lib/skyfall/messages/websocket_message.rb +4 -0
- data/lib/skyfall/operation.rb +14 -12
- data/lib/skyfall/stream.rb +14 -26
- data/lib/skyfall/version.rb +1 -1
- metadata +41 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1002b9dbaf48b9158f4b37d314e7f72d0990bf8290a5ad5d172af5aec9c48e38
|
4
|
+
data.tar.gz: 2a7cf444f30a13135e0848cbf0ad6c1900d9210e0799117e0612d5c52a93b2a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 600eaf8dd34c393b592a6490848d9e981c9ff0fa17fab629d2d640162eecda1248a49944e49d4bb679f732551e75ac209fd09bac85b7a087f81e8b13153c3446
|
7
|
+
data.tar.gz: e8d2c63b039aa7918337b67b77e8d0b511aba81b98d21862cf75a8561d42e72e71214fe16b11f884082fdd8b646e917b840b0369911d07afb32aedc42badc38a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
|
3
|
+
- added heartbeat timer
|
4
|
+
|
5
|
+
## [0.3.1] - 2024-06-28
|
6
|
+
|
7
|
+
- added `app.bsky.graph.starterpack` and `chat.bsky.actor.declaration` record types
|
8
|
+
- added `#account` event type (`AccountMessage`)
|
9
|
+
- added `handle` field to `IdentityMessage`
|
10
|
+
- fixed param validation on `Stream` initialization
|
11
|
+
- reverted the change that added Ruby stdlib dependencies explicitly to the gemspec, since this causes more problems than it's worth - only `base64` is left there, since it's the one now required to be listed
|
12
|
+
|
13
|
+
## [0.3.0] - 2024-03-21
|
14
|
+
|
15
|
+
- added support for labeller firehose, served by labeller services at the `com.atproto.label.subscribeLabels` endpoint (aliased as `:subscribe_labels`)
|
16
|
+
- the `#labels` messages from the labeller firehose are parsed into a `LabelsMessage`, which includes a `labels` array of `Label` objects
|
17
|
+
- `Stream` callbacks can now also be assigned via setters, e.g. `stream.on_message = proc { ... }`
|
18
|
+
- added default error handler to `Stream` which logs the error to `$stdout` - set `stream.on_error = nil` to disable
|
19
|
+
- added Ruby stdlib dependencies explicitly to the gemspec - fixes a warning in Ruby 3.3 when requiring `base64`, which will be extracted as an optional gem in 3.4
|
20
|
+
|
1
21
|
## [0.2.5] - 2024-03-14
|
2
22
|
|
3
23
|
- added `:bsky_labeler` record type symbol & collection constant
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Skyfall
|
2
2
|
|
3
|
-
|
3
|
+
A Ruby gem for streaming data from the Bluesky/AtProto firehose 🦋
|
4
|
+
|
5
|
+
> [!NOTE]
|
6
|
+
> ATProto Ruby gems collection: [skyfall](https://github.com/mackuba/skyfall) | [blue_factory](https://github.com/mackuba/blue_factory) | [minisky](https://github.com/mackuba/minisky) | [didkit](https://github.com/mackuba/didkit)
|
4
7
|
|
5
8
|
|
6
9
|
## What does it do
|
data/lib/skyfall/collection.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
module Skyfall
|
2
2
|
module Collection
|
3
|
-
BSKY_PROFILE
|
4
|
-
BSKY_FEED
|
5
|
-
BSKY_LIKE
|
6
|
-
BSKY_POST
|
7
|
-
BSKY_REPOST
|
8
|
-
BSKY_THREADGATE
|
9
|
-
BSKY_BLOCK
|
10
|
-
BSKY_FOLLOW
|
11
|
-
BSKY_LIST
|
12
|
-
BSKY_LISTBLOCK
|
13
|
-
BSKY_LISTITEM
|
14
|
-
|
3
|
+
BSKY_PROFILE = "app.bsky.actor.profile"
|
4
|
+
BSKY_FEED = "app.bsky.feed.generator"
|
5
|
+
BSKY_LIKE = "app.bsky.feed.like"
|
6
|
+
BSKY_POST = "app.bsky.feed.post"
|
7
|
+
BSKY_REPOST = "app.bsky.feed.repost"
|
8
|
+
BSKY_THREADGATE = "app.bsky.feed.threadgate"
|
9
|
+
BSKY_BLOCK = "app.bsky.graph.block"
|
10
|
+
BSKY_FOLLOW = "app.bsky.graph.follow"
|
11
|
+
BSKY_LIST = "app.bsky.graph.list"
|
12
|
+
BSKY_LISTBLOCK = "app.bsky.graph.listblock"
|
13
|
+
BSKY_LISTITEM = "app.bsky.graph.listitem"
|
14
|
+
BSKY_STARTERPACK = "app.bsky.graph.starterpack"
|
15
|
+
BSKY_LABELER = "app.bsky.labeler.service"
|
16
|
+
|
17
|
+
BSKY_CHAT_DECLARATION = "chat.bsky.actor.declaration"
|
15
18
|
end
|
16
19
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Skyfall
|
5
|
+
class Label
|
6
|
+
attr_reader :data
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
@data = data
|
10
|
+
|
11
|
+
raise DecodeError.new("Missing version: #{data}") unless data.has_key?('ver')
|
12
|
+
raise DecodeError.new("Invalid version: #{ver}") unless ver.is_a?(Integer) && ver >= 1
|
13
|
+
raise UnsupportedError.new("Unsupported version: #{ver}") unless ver == 1
|
14
|
+
|
15
|
+
raise DecodeError.new("Missing source: #{data}") unless data.has_key?('src')
|
16
|
+
raise DecodeError.new("Invalid source: #{src}") unless src.is_a?(String) && src.start_with?('did:')
|
17
|
+
|
18
|
+
raise DecodeError.new("Missing uri: #{data}") unless data.has_key?('uri')
|
19
|
+
raise DecodeError.new("Invalid uri: #{uri}") unless uri.is_a?(String)
|
20
|
+
raise DecodeError.new("Invalid uri: #{uri}") unless uri.start_with?('at://') || uri.start_with?('did:')
|
21
|
+
end
|
22
|
+
|
23
|
+
def version
|
24
|
+
@data['ver']
|
25
|
+
end
|
26
|
+
|
27
|
+
def authority
|
28
|
+
@data['src']
|
29
|
+
end
|
30
|
+
|
31
|
+
def subject
|
32
|
+
@data['uri']
|
33
|
+
end
|
34
|
+
|
35
|
+
def cid
|
36
|
+
@cid ||= @data['cid'] && CID.from_json(@data['cid'])
|
37
|
+
end
|
38
|
+
|
39
|
+
def value
|
40
|
+
@data['val']
|
41
|
+
end
|
42
|
+
|
43
|
+
def negation?
|
44
|
+
!!@data['neg']
|
45
|
+
end
|
46
|
+
|
47
|
+
def created_at
|
48
|
+
@created_at ||= Time.parse(@data['cts'])
|
49
|
+
end
|
50
|
+
|
51
|
+
def expires_at
|
52
|
+
@expires_at ||= @data['exp'] && Time.parse(@data['exp'])
|
53
|
+
end
|
54
|
+
|
55
|
+
alias ver version
|
56
|
+
alias src authority
|
57
|
+
alias uri subject
|
58
|
+
alias val value
|
59
|
+
alias neg negation?
|
60
|
+
alias cts created_at
|
61
|
+
alias exp expires_at
|
62
|
+
end
|
63
|
+
end
|
@@ -1,4 +1,9 @@
|
|
1
1
|
module Skyfall
|
2
|
+
|
3
|
+
#
|
4
|
+
# Note: this event type is deprecated and will stop being emitted at some point.
|
5
|
+
# You should instead listen for 'identity' events (Skyfall::IdentityMessage).
|
6
|
+
#
|
2
7
|
class HandleMessage < WebsocketMessage
|
3
8
|
def handle
|
4
9
|
@data_object['handle']
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'websocket_message'
|
2
|
+
require_relative '../label'
|
3
|
+
|
4
|
+
module Skyfall
|
5
|
+
class LabelsMessage
|
6
|
+
using Skyfall::Extensions
|
7
|
+
|
8
|
+
attr_reader :type_object, :data_object
|
9
|
+
attr_reader :type, :seq
|
10
|
+
|
11
|
+
def initialize(type_object, data_object)
|
12
|
+
@type_object = type_object
|
13
|
+
@data_object = data_object
|
14
|
+
|
15
|
+
@type = @type_object['t'][1..-1].to_sym
|
16
|
+
@seq = @data_object['seq']
|
17
|
+
end
|
18
|
+
|
19
|
+
def labels
|
20
|
+
@labels ||= @data_object['labels'].map { |x| Label.new(x) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -8,10 +8,12 @@ module Skyfall
|
|
8
8
|
class WebsocketMessage
|
9
9
|
using Skyfall::Extensions
|
10
10
|
|
11
|
+
require_relative 'account_message'
|
11
12
|
require_relative 'commit_message'
|
12
13
|
require_relative 'handle_message'
|
13
14
|
require_relative 'identity_message'
|
14
15
|
require_relative 'info_message'
|
16
|
+
require_relative 'labels_message'
|
15
17
|
require_relative 'tombstone_message'
|
16
18
|
require_relative 'unknown_message'
|
17
19
|
|
@@ -24,10 +26,12 @@ module Skyfall
|
|
24
26
|
type_object, data_object = decode_cbor_objects(data)
|
25
27
|
|
26
28
|
message_class = case type_object['t']
|
29
|
+
when '#account' then AccountMessage
|
27
30
|
when '#commit' then CommitMessage
|
28
31
|
when '#handle' then HandleMessage
|
29
32
|
when '#identity' then IdentityMessage
|
30
33
|
when '#info' then InfoMessage
|
34
|
+
when '#labels' then LabelsMessage
|
31
35
|
when '#tombstone' then TombstoneMessage
|
32
36
|
else UnknownMessage
|
33
37
|
end
|
data/lib/skyfall/operation.rb
CHANGED
@@ -43,18 +43,20 @@ module Skyfall
|
|
43
43
|
|
44
44
|
def type
|
45
45
|
case collection
|
46
|
-
when Collection::BSKY_BLOCK
|
47
|
-
when Collection::BSKY_FEED
|
48
|
-
when Collection::BSKY_FOLLOW
|
49
|
-
when Collection::BSKY_LABELER
|
50
|
-
when Collection::BSKY_LIKE
|
51
|
-
when Collection::BSKY_LIST
|
52
|
-
when Collection::BSKY_LISTBLOCK
|
53
|
-
when Collection::BSKY_LISTITEM
|
54
|
-
when Collection::BSKY_POST
|
55
|
-
when Collection::BSKY_PROFILE
|
56
|
-
when Collection::BSKY_REPOST
|
57
|
-
when Collection::
|
46
|
+
when Collection::BSKY_BLOCK then :bsky_block
|
47
|
+
when Collection::BSKY_FEED then :bsky_feed
|
48
|
+
when Collection::BSKY_FOLLOW then :bsky_follow
|
49
|
+
when Collection::BSKY_LABELER then :bsky_labeler
|
50
|
+
when Collection::BSKY_LIKE then :bsky_like
|
51
|
+
when Collection::BSKY_LIST then :bsky_list
|
52
|
+
when Collection::BSKY_LISTBLOCK then :bsky_listblock
|
53
|
+
when Collection::BSKY_LISTITEM then :bsky_listitem
|
54
|
+
when Collection::BSKY_POST then :bsky_post
|
55
|
+
when Collection::BSKY_PROFILE then :bsky_profile
|
56
|
+
when Collection::BSKY_REPOST then :bsky_repost
|
57
|
+
when Collection::BSKY_STARTERPACK then :bsky_starterpack
|
58
|
+
when Collection::BSKY_THREADGATE then :bsky_threadgate
|
59
|
+
when Collection::BSKY_CHAT_DECLARATION then :bsky_chat_declaration
|
58
60
|
else :unknown
|
59
61
|
end
|
60
62
|
end
|
data/lib/skyfall/stream.rb
CHANGED
@@ -7,11 +7,15 @@ require 'uri'
|
|
7
7
|
module Skyfall
|
8
8
|
class Stream
|
9
9
|
SUBSCRIBE_REPOS = "com.atproto.sync.subscribeRepos"
|
10
|
+
SUBSCRIBE_LABELS = "com.atproto.label.subscribeLabels"
|
10
11
|
|
11
12
|
NAMED_ENDPOINTS = {
|
12
|
-
:subscribe_repos => SUBSCRIBE_REPOS
|
13
|
+
:subscribe_repos => SUBSCRIBE_REPOS,
|
14
|
+
:subscribe_labels => SUBSCRIBE_LABELS
|
13
15
|
}
|
14
16
|
|
17
|
+
EVENTS = %w(message raw_message connecting connect disconnect reconnect error)
|
18
|
+
|
15
19
|
MAX_RECONNECT_INTERVAL = 300
|
16
20
|
|
17
21
|
attr_accessor :heartbeat_timeout, :heartbeat_interval, :cursor, :auto_reconnect
|
@@ -23,6 +27,8 @@ module Skyfall
|
|
23
27
|
@handlers = {}
|
24
28
|
@auto_reconnect = true
|
25
29
|
@connection_attempts = 0
|
30
|
+
|
31
|
+
@handlers[:error] = proc { |e| puts "ERROR: #{e}" }
|
26
32
|
end
|
27
33
|
|
28
34
|
def connect
|
@@ -104,32 +110,14 @@ module Skyfall
|
|
104
110
|
|
105
111
|
alias close disconnect
|
106
112
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
def on_raw_message(&block)
|
112
|
-
@handlers[:raw_message] = block
|
113
|
-
end
|
114
|
-
|
115
|
-
def on_connecting(&block)
|
116
|
-
@handlers[:connecting] = block
|
117
|
-
end
|
118
|
-
|
119
|
-
def on_connect(&block)
|
120
|
-
@handlers[:connect] = block
|
121
|
-
end
|
122
|
-
|
123
|
-
def on_disconnect(&block)
|
124
|
-
@handlers[:disconnect] = block
|
125
|
-
end
|
126
|
-
|
127
|
-
def on_error(&block)
|
128
|
-
@handlers[:error] = block
|
129
|
-
end
|
113
|
+
EVENTS.each do |event|
|
114
|
+
define_method "on_#{event}" do |&block|
|
115
|
+
@handlers[event.to_sym] = block
|
116
|
+
end
|
130
117
|
|
131
|
-
|
132
|
-
|
118
|
+
define_method "on_#{event}=" do |block|
|
119
|
+
@handlers[event.to_sym] = block
|
120
|
+
end
|
133
121
|
end
|
134
122
|
|
135
123
|
def inspectable_variables
|
data/lib/skyfall/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skyfall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kuba Suder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base32
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 0.3.4
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: base64
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.1'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.1'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: cbor
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,20 +64,40 @@ dependencies:
|
|
50
64
|
- - ">="
|
51
65
|
- !ruby/object:Gem::Version
|
52
66
|
version: 0.5.9.6
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: eventmachine
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.2'
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.2.7
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.2'
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.2.7
|
53
87
|
- !ruby/object:Gem::Dependency
|
54
88
|
name: faye-websocket
|
55
89
|
requirement: !ruby/object:Gem::Requirement
|
56
90
|
requirements:
|
57
91
|
- - "~>"
|
58
92
|
- !ruby/object:Gem::Version
|
59
|
-
version: 0.11
|
93
|
+
version: '0.11'
|
60
94
|
type: :runtime
|
61
95
|
prerelease: false
|
62
96
|
version_requirements: !ruby/object:Gem::Requirement
|
63
97
|
requirements:
|
64
98
|
- - "~>"
|
65
99
|
- !ruby/object:Gem::Version
|
66
|
-
version: 0.11
|
100
|
+
version: '0.11'
|
67
101
|
description: "\n Skyfall is a Ruby library for connecting to the \"firehose\" of
|
68
102
|
the Bluesky social network, i.e. a websocket which\n streams all new posts and
|
69
103
|
everything else happening on the Bluesky network in real time. The code connects
|
@@ -89,10 +123,13 @@ files:
|
|
89
123
|
- lib/skyfall/collection.rb
|
90
124
|
- lib/skyfall/errors.rb
|
91
125
|
- lib/skyfall/extensions.rb
|
126
|
+
- lib/skyfall/label.rb
|
127
|
+
- lib/skyfall/messages/account_message.rb
|
92
128
|
- lib/skyfall/messages/commit_message.rb
|
93
129
|
- lib/skyfall/messages/handle_message.rb
|
94
130
|
- lib/skyfall/messages/identity_message.rb
|
95
131
|
- lib/skyfall/messages/info_message.rb
|
132
|
+
- lib/skyfall/messages/labels_message.rb
|
96
133
|
- lib/skyfall/messages/tombstone_message.rb
|
97
134
|
- lib/skyfall/messages/unknown_message.rb
|
98
135
|
- lib/skyfall/messages/websocket_message.rb
|