tinysky 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 684a3be9f4c117588a0abadfaa148e33fa90d45b8d261fc7e554e053433adc38
4
- data.tar.gz: 68722993bf6155095a02c95caaf538bb1cb56f2ac32f044f09c46c2bd7be9688
3
+ metadata.gz: 276b6d688f7a617d0d2a3ab3b4933f43144b19e7451a7e06fa6c83ad49f80cba
4
+ data.tar.gz: db21e24e978955fe7f4c3087e342e3c2a7eda1f8e2b8ad4983e2a890d0b60562
5
5
  SHA512:
6
- metadata.gz: 9805134a66b69b767c2891fb48fd290b85f7c79f0fe9bb7694786cea6bc5d22344b9de282e0c7047098639f60a064c5c995f4cb84dd695eeffd13c15eb36e200
7
- data.tar.gz: 486fa0974e2756090a2f15c49f178df1707e72e90c486771cccb263f60e7d28cbd18a8b6a8662534b284f489346d6c79064180e565073c60b07ceb1c85347b17
6
+ metadata.gz: 6c9481b63bbf00e0b2fb77b2af51a09321a1dcefbc951675a3297191a5067ab913032cd63865423c6012b12d06fc8c4ee70ce10b89fbb614672e9515551579cb
7
+ data.tar.gz: ab878e737f2f974073323f6baf28ab0b967572aacaae533a37c94ab2a45985351db63a95e8ecf9570af325957084f44c2c84c243bf19300585211b63323708e8
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 4.0.1
data/CHANGELOG.md CHANGED
@@ -22,6 +22,23 @@ The format is based on [Keep a Changelog][] and this project adheres to
22
22
 
23
23
  ### Security
24
24
 
25
+ ## [0.0.4][] - 2026-02-22
26
+
27
+ ### Added
28
+
29
+ * Add update script ([#7][])
30
+ * Add support for link facets ([#15][])
31
+ * Add support for record embeds ([#16][])
32
+
33
+ ### Changed
34
+
35
+ * Use Zeitwerk for loading ([#10][])
36
+ * Update Ruby matrix for CI ([#11][])
37
+ * Upgrade to Ruby 4 ([#12][])
38
+ * Improve CI configuration ([#13][])
39
+ * Extract modules for api details ([#14][])
40
+ * Move to automated release on CI ([#17][])
41
+
25
42
  ## [0.0.3][] - 2024-09-15
26
43
 
27
44
  ### Changed
@@ -45,13 +62,23 @@ The format is based on [Keep a Changelog][] and this project adheres to
45
62
 
46
63
  * Initial release
47
64
 
48
- [Unreleased]: https://github.com/jonallured/tinysky/compare/v0.0.3...HEAD
65
+ [Unreleased]: https://github.com/jonallured/tinysky/compare/v0.0.4...HEAD
49
66
 
50
67
  [0.0.1]: https://github.com/jonallured/tinysky/releases/tag/v0.0.1
51
68
  [0.0.2]: https://github.com/jonallured/tinysky/releases/tag/v0.0.2
52
- [0.0.2]: https://github.com/jonallured/tinysky/releases/tag/v0.0.3
69
+ [0.0.3]: https://github.com/jonallured/tinysky/releases/tag/v0.0.3
70
+ [0.0.4]: https://github.com/jonallured/tinysky/releases/tag/v0.0.4
53
71
 
54
72
  [#3]: https://github.com/jonallured/tinysky/pull/3
55
73
  [#4]: https://github.com/jonallured/tinysky/pull/4
56
74
  [#5]: https://github.com/jonallured/tinysky/pull/5
57
75
  [#6]: https://github.com/jonallured/tinysky/pull/6
76
+ [#7]: https://github.com/jonallured/tinysky/pull/7
77
+ [#10]: https://github.com/jonallured/tinysky/pull/10
78
+ [#11]: https://github.com/jonallured/tinysky/pull/11
79
+ [#12]: https://github.com/jonallured/tinysky/pull/12
80
+ [#13]: https://github.com/jonallured/tinysky/pull/13
81
+ [#14]: https://github.com/jonallured/tinysky/pull/14
82
+ [#15]: https://github.com/jonallured/tinysky/pull/15
83
+ [#16]: https://github.com/jonallured/tinysky/pull/16
84
+ [#17]: https://github.com/jonallured/tinysky/pull/17
data/README.md CHANGED
@@ -35,6 +35,21 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
35
35
 
36
36
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
37
 
38
+ ## Releasing
39
+
40
+ The release process is automated but should start with a commit to update the
41
+ CHANGELOG. This commit should add the new version and then update the Unreleased
42
+ section back to defaults. It should also update the links. Once that's done then
43
+ the actual process can be kicked off like so:
44
+
45
+ ```
46
+ $ bin/release
47
+ ```
48
+
49
+ Which will create a commit that bumps the patch version, push the commit to
50
+ GitHub and then push the tag that triggers the release.yml workflow. That
51
+ workflow will run tests and then push to RubyGems.org.
52
+
38
53
  ## Contributing
39
54
 
40
55
  Bug reports and pull requests are welcome on GitHub at https://github.com/jonallured/tinysky.
@@ -43,5 +58,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/jonall
43
58
 
44
59
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
45
60
 
46
- [actions]: https://github.com/jonallured/tinysky/actions
61
+ [actions]: https://github.com/jonallured/tinysky/actions/workflows/main.yml
47
62
  [badge]: https://github.com/jonallured/tinysky/actions/workflows/main.yml/badge.svg
data/Rakefile CHANGED
@@ -2,5 +2,6 @@ require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
  require "standard/rake"
4
4
 
5
- RSpec::Core::RakeTask.new(:spec)
5
+ RSpec::Core::RakeTask.new(:spec) { |t| t.verbose = false }
6
+
6
7
  task default: %i[standard spec]
@@ -0,0 +1,37 @@
1
+ require "bundler/setup"
2
+ require "tinysky"
3
+
4
+ BlogPost = Struct.new(:url, :title, :description, :image_url)
5
+
6
+ blog_post = BlogPost.new(
7
+ "https://www.jonallured.com/posts/2026/02/14/upgrading-to-ruby-four-oh.html",
8
+ "Upgrading to Ruby 4.0",
9
+ "Ruby 4.0 was released a couple months ago on Christmas and I had been meaning to upgrade for a while. I noticed that version 4.0.1 came out too so that's always a good sign that things are stable and ready for prime time.",
10
+ "https://www.jonallured.com/images/post-95/social-share.png"
11
+ )
12
+
13
+ credentials_path = "/Users/jon/Desktop/tinysky_credentials.json"
14
+ credentials = JSON.load_file(credentials_path, symbolize_names: true)
15
+ client = Tinysky::Client.new(credentials)
16
+
17
+ blob_data = Faraday.get(blog_post.image_url).body
18
+ content_type = "image/png"
19
+ upload_response = client.upload_blob(blob_data, content_type)
20
+ thumb = upload_response.body["blob"]
21
+
22
+ embed = Tinysky::ExternalEmbed.new(
23
+ description: blog_post.description,
24
+ thumb: thumb,
25
+ title: blog_post.title,
26
+ uri: blog_post.url
27
+ )
28
+
29
+ message = "New blog post: https://www.jonallured.com/posts/2026/02/14/upgrading-to-ruby-four-oh.html"
30
+ facets = Tinysky::FacetParser.for(message)
31
+
32
+ record_options = {
33
+ embed: embed,
34
+ facets: facets
35
+ }
36
+
37
+ client.create_record(message, record_options)
@@ -0,0 +1,12 @@
1
+ require "bundler/setup"
2
+ require "tinysky"
3
+
4
+ credentials_path = "/Users/jon/Desktop/tinysky_credentials.json"
5
+ credentials = JSON.load_file(credentials_path, symbolize_names: true)
6
+ client = Tinysky::Client.new(credentials)
7
+
8
+ text = "Upgrading to Ruby 4.0 https://www.jonallured.com/posts/2026/02/14/upgrading-to-ruby-four-oh.html"
9
+ facets = Tinysky::FacetParser.for(text)
10
+ options = {facets: facets}
11
+
12
+ client.create_record(text, options)
@@ -16,7 +16,8 @@ module Tinysky
16
16
  password: @credentials[:app_password]
17
17
  }
18
18
 
19
- response = @connection.post(CREATE_SESSION_PATH, body)
19
+ path = Tinysky::Endpoints::SERVER_CREATE_SESSION
20
+ response = @connection.post(path, body)
20
21
 
21
22
  @access_jwt = response.body["accessJwt"]
22
23
  payload, _header = JWT.decode(@access_jwt, nil, false)
@@ -25,25 +26,33 @@ module Tinysky
25
26
  response
26
27
  end
27
28
 
28
- def create_record(text)
29
+ def create_record(text, options)
29
30
  create_session if expired_token?
30
31
 
31
- record = {
32
- "$type" => POST_LEXICON_TYPE,
33
- "createdAt" => DateTime.now.iso8601,
34
- "langs" => ["en-US"],
35
- "text" => text
36
- }
32
+ feed_post = FeedPost.new(text, options)
37
33
 
38
34
  body = {
39
- collection: POST_LEXICON_TYPE,
40
- record: record,
35
+ collection: Tinysky::Lexicon::FEED_POST,
36
+ record: feed_post.to_hash,
41
37
  repo: @credentials[:handle]
42
38
  }
43
39
 
44
40
  headers = {"Authorization" => "Bearer #{@access_jwt}"}
45
41
 
46
- @connection.post(CREATE_RECORD_PATH, body, headers)
42
+ path = Tinysky::Endpoints::REPO_CREATE_RECORD
43
+ @connection.post(path, body, headers)
44
+ end
45
+
46
+ def upload_blob(blob_data, content_type)
47
+ create_session if expired_token?
48
+
49
+ headers = {
50
+ "Authorization" => "Bearer #{@access_jwt}",
51
+ "Content-Type" => content_type
52
+ }
53
+
54
+ path = Tinysky::Endpoints::REPO_UPLOAD_BLOB
55
+ @connection.post(path, blob_data, headers)
47
56
  end
48
57
 
49
58
  private
@@ -0,0 +1,7 @@
1
+ module Tinysky
2
+ module Endpoints
3
+ REPO_CREATE_RECORD = "/xrpc/com.atproto.repo.createRecord"
4
+ REPO_UPLOAD_BLOB = "/xrpc/com.atproto.repo.uploadBlob"
5
+ SERVER_CREATE_SESSION = "/xrpc/com.atproto.server.createSession"
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module Tinysky
2
+ class ExternalEmbed
3
+ def initialize(attrs)
4
+ @description = attrs[:description]
5
+ @thumb = attrs[:thumb]
6
+ @title = attrs[:title]
7
+ @uri = attrs[:uri]
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ "$type" => Tinysky::Lexicon::EXTERNAL_EMBED,
13
+ "external" => {
14
+ "description" => @description,
15
+ "thumb" => @thumb,
16
+ "title" => @title,
17
+ "uri" => @uri
18
+ }
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Tinysky
2
+ class FacetParser
3
+ URL_PATTERN = /https?:\/\/\S+/
4
+
5
+ def self.for(text)
6
+ parser = new(text)
7
+ parser.find_facets
8
+ end
9
+
10
+ def initialize(text)
11
+ @text = text || ""
12
+ end
13
+
14
+ def find_facets
15
+ scan_enumerator = @text.enum_for(:scan, URL_PATTERN)
16
+
17
+ scan_enumerator.map do |url|
18
+ char_start = Regexp.last_match.begin(0)
19
+ byte_start = @text[0, char_start].bytesize
20
+ byte_end = byte_start + url.bytesize
21
+ LinkFacet.new(byte_start, byte_end, url)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module Tinysky
2
+ class FeedPost
3
+ def initialize(text, options)
4
+ @text = text
5
+ @options = options
6
+ end
7
+
8
+ def to_hash
9
+ hsh = {
10
+ "$type" => Tinysky::Lexicon::FEED_POST,
11
+ "createdAt" => created_at,
12
+ "langs" => ["en-US"],
13
+ "text" => @text
14
+ }
15
+
16
+ hsh["embed"] = embed.to_hash unless embed.nil?
17
+ hsh["facets"] = facets.map(&:to_hash) if facets.any?
18
+
19
+ hsh
20
+ end
21
+
22
+ private
23
+
24
+ def created_at
25
+ as_of = @options[:as_of] || DateTime.now
26
+ as_of.iso8601
27
+ end
28
+
29
+ def embed
30
+ @options[:embed]
31
+ end
32
+
33
+ def facets
34
+ return [] if @options[:facets].nil?
35
+
36
+ @options[:facets]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ module Tinysky
2
+ module Lexicon
3
+ EXTERNAL_EMBED = "app.bsky.embed.external"
4
+ FEED_POST = "app.bsky.feed.post"
5
+ LINK_FACET = "app.bsky.richtext.facet#link"
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ module Tinysky
2
+ class LinkFacet
3
+ def initialize(byte_start, byte_end, uri)
4
+ @byte_start = byte_start
5
+ @byte_end = byte_end
6
+ @uri = uri
7
+ end
8
+
9
+ def to_hash
10
+ {
11
+ "features" => [
12
+ {
13
+ "$type" => Tinysky::Lexicon::LINK_FACET,
14
+ "uri" => @uri
15
+ }
16
+ ],
17
+ "index" => {
18
+ "byteEnd" => @byte_end,
19
+ "byteStart" => @byte_start
20
+ }
21
+ }
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Tinysky
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/tinysky.rb CHANGED
@@ -1,17 +1,13 @@
1
1
  require "faraday"
2
2
  require "jwt"
3
+ require "zeitwerk"
3
4
 
4
- require_relative "tinysky/version"
5
- require_relative "tinysky/client"
5
+ loader = Zeitwerk::Loader.for_gem
6
+ loader.setup
6
7
 
7
8
  module Tinysky
8
9
  ROOT_URL = "https://bsky.social"
9
10
 
10
- CREATE_RECORD_PATH = "/xrpc/com.atproto.repo.createRecord"
11
- CREATE_SESSION_PATH = "/xrpc/com.atproto.server.createSession"
12
-
13
- POST_LEXICON_TYPE = "app.bsky.feed.post"
14
-
15
11
  def self.generate_connection
16
12
  Faraday.new(url: ROOT_URL) do |f|
17
13
  f.request :json
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinysky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Allured
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-09-15 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -38,6 +37,20 @@ dependencies:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
39
  version: '2'
40
+ - !ruby/object:Gem::Dependency
41
+ name: zeitwerk
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
41
54
  description: A tiny client gem for the Bluesky API that focuses on creating posts.
42
55
  email:
43
56
  - jon@jonallured.com
@@ -47,21 +60,28 @@ extra_rdoc_files: []
47
60
  files:
48
61
  - ".rspec"
49
62
  - ".standard.yml"
63
+ - ".tool-versions"
50
64
  - CHANGELOG.md
51
65
  - LICENSE.txt
52
66
  - README.md
53
67
  - Rakefile
68
+ - examples/create_record_with_embed.rb
69
+ - examples/create_record_with_facet.rb
54
70
  - lib/tinysky.rb
55
71
  - lib/tinysky/client.rb
72
+ - lib/tinysky/endpoints.rb
73
+ - lib/tinysky/external_embed.rb
74
+ - lib/tinysky/facet_parser.rb
75
+ - lib/tinysky/feed_post.rb
76
+ - lib/tinysky/lexicon.rb
77
+ - lib/tinysky/link_facet.rb
56
78
  - lib/tinysky/version.rb
57
79
  - sig/tinysky.rbs
58
- - tinysky.gemspec
59
80
  homepage: https://github.com/jonallured/tinysky
60
81
  licenses:
61
82
  - MIT
62
83
  metadata:
63
84
  homepage_uri: https://github.com/jonallured/tinysky
64
- post_install_message:
65
85
  rdoc_options: []
66
86
  require_paths:
67
87
  - lib
@@ -69,15 +89,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
89
  requirements:
70
90
  - - ">="
71
91
  - !ruby/object:Gem::Version
72
- version: 2.6.0
92
+ version: '3.2'
73
93
  required_rubygems_version: !ruby/object:Gem::Requirement
74
94
  requirements:
75
95
  - - ">="
76
96
  - !ruby/object:Gem::Version
77
97
  version: '0'
78
98
  requirements: []
79
- rubygems_version: 3.5.16
80
- signing_key:
99
+ rubygems_version: 4.0.3
81
100
  specification_version: 4
82
101
  summary: Tiny client for the Bluesky API.
83
102
  test_files: []
data/tinysky.gemspec DELETED
@@ -1,30 +0,0 @@
1
- require_relative "lib/tinysky/version"
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = "tinysky"
5
- spec.version = Tinysky::VERSION
6
- spec.authors = ["Jon Allured"]
7
- spec.email = ["jon@jonallured.com"]
8
-
9
- spec.summary = "Tiny client for the Bluesky API."
10
- spec.description = "A tiny client gem for the Bluesky API that focuses on creating posts."
11
- spec.homepage = "https://github.com/jonallured/tinysky"
12
- spec.license = "MIT"
13
- spec.required_ruby_version = ">= 2.6.0"
14
-
15
- spec.metadata["homepage_uri"] = spec.homepage
16
-
17
- spec.files = Dir.chdir(__dir__) do
18
- `git ls-files -z`.split("\x0").reject do |f|
19
- (File.expand_path(f) == __FILE__) ||
20
- f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
21
- end
22
- end
23
-
24
- spec.bindir = "exe"
25
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26
- spec.require_paths = ["lib"]
27
-
28
- spec.add_dependency "faraday", "~> 2"
29
- spec.add_dependency "jwt", "~> 2"
30
- end