at_protocol 0.0.4.1 → 0.0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/at_protocol/extconf.rb +3 -0
- data/ext/at_protocol/tid.c +130 -0
- data/lib/at_protocol/at_uri.rb +4 -0
- data/lib/at_protocol/collection.rb +3 -15
- data/lib/at_protocol/requests.rb +39 -20
- data/lib/at_protocol/session.rb +4 -0
- data/lib/at_protocol/tid_ext.rb +19 -0
- data/lib/at_protocol/version.rb +1 -1
- data/lib/at_protocol/writes.rb +6 -5
- data/lib/at_protocol.rb +13 -1
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0dd450b9e79e59d5df52330a9e0fd00135db4e2a8eddce654780133835ca69f
|
4
|
+
data.tar.gz: bda2354c8c63d85eee0075c5fda834e1018e31e9c8b5daba221695644998e338
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19eec8bd3383a55ae752ed3561bcced63c5a438fe1060dcd1a08fe46249e56d469b7ded6a026c73d82a84a78ef4fd2af35572ccd610fa854287b1babf43e3e8f
|
7
|
+
data.tar.gz: e8d0dc32c9e1a4101fb8dc30b0ca16a49955f3d096fbc75d36ce20486590cefb67df66c83268dabde43716495247706b6f8a7599a6b530a67b75d1b096c621db
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <time.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdint.h>
|
5
|
+
#include <math.h>
|
6
|
+
|
7
|
+
static VALUE atproto_module;
|
8
|
+
static VALUE tid_class;
|
9
|
+
const char b32_chars[32] = "234567abcdefghijklmnopqrstuvwxyz";
|
10
|
+
|
11
|
+
typedef struct {
|
12
|
+
uint64_t timestamp;
|
13
|
+
uint64_t clock_identifier;
|
14
|
+
} TID;
|
15
|
+
|
16
|
+
static VALUE tid_alloc(VALUE klass) {
|
17
|
+
TID *tid = ALLOC(TID);
|
18
|
+
return Data_Wrap_Struct(klass, 0, xfree, tid);
|
19
|
+
}
|
20
|
+
|
21
|
+
static VALUE tid_initialize(int argc, VALUE *argv, VALUE self) {
|
22
|
+
VALUE time_arg = Qnil;
|
23
|
+
rb_scan_args(argc, argv, "01", &time_arg);
|
24
|
+
|
25
|
+
TID *tid;
|
26
|
+
Data_Get_Struct(self, TID, tid);
|
27
|
+
|
28
|
+
if (NIL_P(time_arg)) {
|
29
|
+
struct timeval tv;
|
30
|
+
gettimeofday(&tv, NULL);
|
31
|
+
tid->timestamp = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
|
32
|
+
} else {
|
33
|
+
if (!rb_obj_is_kind_of(time_arg, rb_cTime)) {
|
34
|
+
rb_raise(rb_eTypeError, "Argument must be a Time object or nil");
|
35
|
+
return Qnil;
|
36
|
+
}
|
37
|
+
|
38
|
+
struct timeval tv;
|
39
|
+
tv.tv_sec = NUM2LONG(rb_funcall(time_arg, rb_intern("tv_sec"), 0));
|
40
|
+
tv.tv_usec = NUM2LONG(rb_funcall(time_arg, rb_intern("tv_usec"), 0));
|
41
|
+
tid->timestamp = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
|
42
|
+
}
|
43
|
+
|
44
|
+
tid->clock_identifier = rand() & 0x3FF;
|
45
|
+
|
46
|
+
return self;
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE tid_to_time(VALUE self) {
|
50
|
+
TID *tid;
|
51
|
+
Data_Get_Struct(self, TID, tid);
|
52
|
+
|
53
|
+
VALUE sec = LL2NUM(tid->timestamp / 1000000);
|
54
|
+
VALUE usec = LL2NUM(tid->timestamp % 1000000);
|
55
|
+
|
56
|
+
return rb_funcall(rb_cTime, rb_intern("at"), 2, sec, usec);
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE tid_to_s(VALUE self) {
|
60
|
+
TID *tid;
|
61
|
+
Data_Get_Struct(self, TID, tid);
|
62
|
+
|
63
|
+
char tid_str[14];
|
64
|
+
for (int i = 0; i < 11; i++) {
|
65
|
+
int index = (int)((tid->timestamp >> (50 - i * 5)) & 0x1F);
|
66
|
+
tid_str[i] = b32_chars[index];
|
67
|
+
}
|
68
|
+
tid_str[11] = b32_chars[(int)(tid->clock_identifier >> 6) & 0x1F];
|
69
|
+
tid_str[12] = b32_chars[(int)tid->clock_identifier & 0x1F];
|
70
|
+
tid_str[13] = '\0';
|
71
|
+
|
72
|
+
return rb_str_new_cstr(tid_str);
|
73
|
+
}
|
74
|
+
|
75
|
+
static VALUE tid_from_string(VALUE klass, VALUE str) {
|
76
|
+
Check_Type(str, T_STRING);
|
77
|
+
|
78
|
+
TID *tid;
|
79
|
+
VALUE tid_obj = Data_Make_Struct(klass, TID, NULL, xfree, tid);
|
80
|
+
|
81
|
+
if (RSTRING_LEN(str) != 13) {
|
82
|
+
rb_raise(rb_eArgError, "TID string must be 13 characters long");
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
char tid_str[14];
|
87
|
+
strncpy(tid_str, StringValueCStr(str), sizeof(tid_str));
|
88
|
+
tid_str[13] = '\0';
|
89
|
+
|
90
|
+
// Convert the TID string back to a TID object
|
91
|
+
uint64_t timestamp = 0;
|
92
|
+
for (int i = 0; i < 11; i++) {
|
93
|
+
char c = tid_str[i];
|
94
|
+
const char *pos = strchr(b32_chars, c);
|
95
|
+
if (pos == NULL) {
|
96
|
+
rb_raise(rb_eArgError, "Invalid character in TID string");
|
97
|
+
return Qnil;
|
98
|
+
}
|
99
|
+
int index = (int)(pos - b32_chars);
|
100
|
+
timestamp = (timestamp << 5) | (index & 0x1F);
|
101
|
+
}
|
102
|
+
|
103
|
+
uint64_t clock_identifier = 0;
|
104
|
+
for (int i = 11; i < 13; i++) {
|
105
|
+
char c = tid_str[i];
|
106
|
+
const char *pos = strchr(b32_chars, c);
|
107
|
+
if (pos == NULL) {
|
108
|
+
rb_raise(rb_eArgError, "Invalid character in TID string");
|
109
|
+
return Qnil;
|
110
|
+
}
|
111
|
+
int index = (int)(pos - b32_chars);
|
112
|
+
clock_identifier = (clock_identifier << 5) | (index & 0x1F);
|
113
|
+
}
|
114
|
+
|
115
|
+
tid->timestamp = timestamp;
|
116
|
+
tid->clock_identifier = clock_identifier;
|
117
|
+
|
118
|
+
return tid_obj;
|
119
|
+
}
|
120
|
+
|
121
|
+
void Init_tid(void) {
|
122
|
+
atproto_module = rb_define_module("ATProto");
|
123
|
+
|
124
|
+
tid_class = rb_define_class_under(atproto_module, "TID", rb_cObject);
|
125
|
+
rb_define_alloc_func(tid_class, tid_alloc);
|
126
|
+
rb_define_method(tid_class, "initialize", tid_initialize, -1);
|
127
|
+
rb_define_method(tid_class, "to_time", tid_to_time, 0);
|
128
|
+
rb_define_method(tid_class, "to_s", tid_to_s, 0);
|
129
|
+
rb_define_singleton_method(tid_class, "from_string", tid_from_string, 1);
|
130
|
+
}
|
data/lib/at_protocol/at_uri.rb
CHANGED
@@ -9,22 +9,10 @@ module ATProto
|
|
9
9
|
const(:repo, ATProto::Repo)
|
10
10
|
const(:collection, String)
|
11
11
|
|
12
|
-
sig { params(
|
13
|
-
|
14
|
-
def list(limit = 10)
|
15
|
-
self.repo.xrpc
|
16
|
-
.get.com_atproto_repo_listRecords(
|
17
|
-
repo: self.repo.did,
|
18
|
-
collection: self.collection,
|
19
|
-
limit: limit,
|
20
|
-
)["records"]
|
21
|
-
.map { |record|
|
22
|
-
ATProto::Record.from_hash(record)
|
23
|
-
}
|
24
|
-
end
|
12
|
+
sig { params(count: T.nilable(Integer)).returns(T::Array[ATProto::Record]) }
|
25
13
|
|
26
|
-
def
|
27
|
-
T.must(get_paginated_data(self.repo, :com_atproto_repo_listRecords.to_s, key: "records", params: { repo: self.repo.to_s, collection: self.to_s }, cursor: nil) do |record|
|
14
|
+
def list(count = nil)
|
15
|
+
T.must(get_paginated_data(self.repo, :com_atproto_repo_listRecords.to_s, key: "records", params: { repo: self.repo.to_s, collection: self.to_s }, count: count, cursor: nil) do |record|
|
28
16
|
ATProto::Record.from_hash(record)
|
29
17
|
end)
|
30
18
|
end
|
data/lib/at_protocol/requests.rb
CHANGED
@@ -78,6 +78,9 @@ module ATProto
|
|
78
78
|
cursor: T.nilable(
|
79
79
|
String
|
80
80
|
),
|
81
|
+
count: T.nilable(
|
82
|
+
Integer
|
83
|
+
),
|
81
84
|
map_block: T.nilable(Proc),
|
82
85
|
)
|
83
86
|
.returns(T
|
@@ -86,7 +89,7 @@ module ATProto
|
|
86
89
|
))
|
87
90
|
}
|
88
91
|
|
89
|
-
def get_paginated_data(session, method, key:, params:, cursor: nil, &map_block)
|
92
|
+
def get_paginated_data(session, method, key:, params:, cursor: nil, count: nil, &map_block)
|
90
93
|
params.merge({ limit: 100, cursor: cursor }).then do |send_data|
|
91
94
|
session.xrpc.get.public_send(method, **send_data).then do |response|
|
92
95
|
response.dig(key).then do |data|
|
@@ -94,26 +97,19 @@ module ATProto
|
|
94
97
|
return []
|
95
98
|
end
|
96
99
|
|
97
|
-
if block_given?
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
return results
|
102
|
-
else
|
103
|
-
get_paginated_data(session, method, key: key, params: params, cursor: next_cursor, &map_block).then do |next_results|
|
104
|
-
return results + next_results
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
100
|
+
results = if block_given?
|
101
|
+
data.map(&map_block)
|
102
|
+
else
|
103
|
+
data
|
108
104
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
105
|
+
|
106
|
+
response.dig("cursor").then do |next_cursor|
|
107
|
+
if next_cursor.nil? || (count && results.length >= count)
|
108
|
+
return results[0..count]
|
109
|
+
else
|
110
|
+
remaining_count = count ? count - results.length : nil
|
111
|
+
get_paginated_data(session, method, key: key, params: params, cursor: next_cursor, count: remaining_count, &map_block).then do |next_results|
|
112
|
+
return (results + next_results)
|
117
113
|
end
|
118
114
|
end
|
119
115
|
end
|
@@ -123,3 +119,26 @@ module ATProto
|
|
123
119
|
end
|
124
120
|
end
|
125
121
|
end
|
122
|
+
|
123
|
+
module ATProto
|
124
|
+
module RequestUtils
|
125
|
+
class XRPCResponseCode < T::Enum
|
126
|
+
enums do
|
127
|
+
Unknown = new(1)
|
128
|
+
InvalidResponse = new(2)
|
129
|
+
Success = new(200)
|
130
|
+
InvalidRequest = new(400)
|
131
|
+
AuthRequired = new(401)
|
132
|
+
Forbidden = new(403)
|
133
|
+
XRPCNotSupported = new(404)
|
134
|
+
PayloadTooLarge = new(413)
|
135
|
+
RateLimitExceeded = new(429)
|
136
|
+
InternalServerError = new(500)
|
137
|
+
MethodNotImplemented = new(501)
|
138
|
+
UpstreamFailure = new(502)
|
139
|
+
NotEnoughResouces = new(503)
|
140
|
+
UpstreamTimeout = new(504)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/at_protocol/session.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "at_protocol/tid"
|
2
|
+
|
3
|
+
class Time
|
4
|
+
def to_tid
|
5
|
+
ATProto::TID.new(self)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class String
|
10
|
+
def to_tid
|
11
|
+
ATProto::TID.from_string(self)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ATProto::TID
|
16
|
+
def inspect
|
17
|
+
"#<ATProto::TID(#{self.to_s})>"
|
18
|
+
end
|
19
|
+
end
|
data/lib/at_protocol/version.rb
CHANGED
data/lib/at_protocol/writes.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# typed: true
|
2
2
|
module ATProto
|
3
|
+
extend T::Sig
|
4
|
+
|
3
5
|
class Writes < T::Struct
|
4
6
|
class Write < T::Struct
|
5
7
|
class Action < T::Enum
|
@@ -101,14 +103,13 @@ module ATProto
|
|
101
103
|
|
102
104
|
class << self
|
103
105
|
extend T::Sig
|
104
|
-
sig { params(block: Proc).returns(T::Array[Write]) }
|
105
|
-
|
106
|
-
def generate(&block)
|
107
|
-
Collector.new.instance_eval(&block)
|
108
|
-
end
|
109
106
|
end
|
110
107
|
end
|
111
108
|
|
109
|
+
def self.Writes(session, &block)
|
110
|
+
Writes.new(writes: Writes::Collector.new.instance_eval(&block), session: session, repo: Repo.new(session.did))
|
111
|
+
end
|
112
|
+
|
112
113
|
class Writes
|
113
114
|
class Collector
|
114
115
|
include RequestUtils
|
data/lib/at_protocol.rb
CHANGED
@@ -15,9 +15,21 @@ class Class
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
module ATProto
|
19
|
+
class << self
|
20
|
+
def method_missing(method_name, *args, &block)
|
21
|
+
if const_defined?(method_name)
|
22
|
+
Object.const_get(method_name).new(*args, &block)
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
18
30
|
require "skyfall/cid"
|
19
31
|
require "xrpc"
|
20
32
|
|
21
|
-
%w(requests session repo collection at_uri writes record record/strongref).each do |name|
|
33
|
+
%w(requests session repo collection at_uri writes record record/strongref tid_ext).each do |name|
|
22
34
|
require "at_protocol/#{name}"
|
23
35
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: at_protocol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.4.
|
4
|
+
version: 0.0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shreyan Jain
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-10-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: xrpc
|
@@ -25,13 +25,30 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 0.1.5
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake-compiler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
description: A Ruby gem for interacting with AT Protocol
|
29
43
|
email:
|
30
44
|
- shreyan.jain.9@outlook.com
|
31
45
|
executables: []
|
32
|
-
extensions:
|
46
|
+
extensions:
|
47
|
+
- ext/at_protocol/extconf.rb
|
33
48
|
extra_rdoc_files: []
|
34
49
|
files:
|
50
|
+
- "./ext/at_protocol/extconf.rb"
|
51
|
+
- "./ext/at_protocol/tid.c"
|
35
52
|
- "./lib/at_protocol.rb"
|
36
53
|
- "./lib/at_protocol/at_uri.rb"
|
37
54
|
- "./lib/at_protocol/collection.rb"
|
@@ -40,8 +57,10 @@ files:
|
|
40
57
|
- "./lib/at_protocol/repo.rb"
|
41
58
|
- "./lib/at_protocol/requests.rb"
|
42
59
|
- "./lib/at_protocol/session.rb"
|
60
|
+
- "./lib/at_protocol/tid_ext.rb"
|
43
61
|
- "./lib/at_protocol/version.rb"
|
44
62
|
- "./lib/at_protocol/writes.rb"
|
63
|
+
- ext/at_protocol/extconf.rb
|
45
64
|
homepage: https://github.com/ShreyanJain9/at_protocol
|
46
65
|
licenses:
|
47
66
|
- MIT
|
@@ -50,6 +69,7 @@ post_install_message:
|
|
50
69
|
rdoc_options: []
|
51
70
|
require_paths:
|
52
71
|
- lib
|
72
|
+
- ext
|
53
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
54
74
|
requirements:
|
55
75
|
- - ">="
|