tinysky 0.0.3 → 0.0.5

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: 42a6cdcc2883a1b16c4d3017330962d571c39a5f2fc9116834c1bfce5f39289a
4
+ data.tar.gz: 2feddc740759b5383cfdfeb0ed86643d7b61795099fe60110731b295208846f5
5
5
  SHA512:
6
- metadata.gz: 9805134a66b69b767c2891fb48fd290b85f7c79f0fe9bb7694786cea6bc5d22344b9de282e0c7047098639f60a064c5c995f4cb84dd695eeffd13c15eb36e200
7
- data.tar.gz: 486fa0974e2756090a2f15c49f178df1707e72e90c486771cccb263f60e7d28cbd18a8b6a8662534b284f489346d6c79064180e565073c60b07ceb1c85347b17
6
+ metadata.gz: 5fc4692c5a2e6a14ef65783ed5075c4f6dfdeb2569019e177aedcd2d0cf90feb4a43dce87dba0a0fb61eb2548f9aec294174318365dad1eea5a25d8064abd6bd
7
+ data.tar.gz: 2bb76a00d7b8719dfa9becc26f7da08742b6a77ae2546b1b6f19fd56cba2418cfe62cc2dc6fe13fa2d218879de2aa6e183f0306bc3bfcf49eabbf71a2c71ce7b
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 4.0.1
data/CHANGELOG.md CHANGED
@@ -22,6 +22,29 @@ The format is based on [Keep a Changelog][] and this project adheres to
22
22
 
23
23
  ### Security
24
24
 
25
+ ## [0.0.5][] - 2026-03-03
26
+
27
+ ### Changed
28
+
29
+ * Upgrade JWT dependency ([#18][])
30
+
31
+ ## [0.0.4][] - 2026-02-22
32
+
33
+ ### Added
34
+
35
+ * Add update script ([#7][])
36
+ * Add support for link facets ([#15][])
37
+ * Add support for record embeds ([#16][])
38
+
39
+ ### Changed
40
+
41
+ * Use Zeitwerk for loading ([#10][])
42
+ * Update Ruby matrix for CI ([#11][])
43
+ * Upgrade to Ruby 4 ([#12][])
44
+ * Improve CI configuration ([#13][])
45
+ * Extract modules for api details ([#14][])
46
+ * Move to automated release on CI ([#17][])
47
+
25
48
  ## [0.0.3][] - 2024-09-15
26
49
 
27
50
  ### Changed
@@ -45,13 +68,25 @@ The format is based on [Keep a Changelog][] and this project adheres to
45
68
 
46
69
  * Initial release
47
70
 
48
- [Unreleased]: https://github.com/jonallured/tinysky/compare/v0.0.3...HEAD
71
+ [Unreleased]: https://github.com/jonallured/tinysky/compare/v0.0.5...HEAD
49
72
 
50
73
  [0.0.1]: https://github.com/jonallured/tinysky/releases/tag/v0.0.1
51
74
  [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
75
+ [0.0.3]: https://github.com/jonallured/tinysky/releases/tag/v0.0.3
76
+ [0.0.4]: https://github.com/jonallured/tinysky/releases/tag/v0.0.4
77
+ [0.0.5]: https://github.com/jonallured/tinysky/releases/tag/v0.0.5
53
78
 
54
79
  [#3]: https://github.com/jonallured/tinysky/pull/3
55
80
  [#4]: https://github.com/jonallured/tinysky/pull/4
56
81
  [#5]: https://github.com/jonallured/tinysky/pull/5
57
82
  [#6]: https://github.com/jonallured/tinysky/pull/6
83
+ [#7]: https://github.com/jonallured/tinysky/pull/7
84
+ [#10]: https://github.com/jonallured/tinysky/pull/10
85
+ [#11]: https://github.com/jonallured/tinysky/pull/11
86
+ [#12]: https://github.com/jonallured/tinysky/pull/12
87
+ [#13]: https://github.com/jonallured/tinysky/pull/13
88
+ [#14]: https://github.com/jonallured/tinysky/pull/14
89
+ [#15]: https://github.com/jonallured/tinysky/pull/15
90
+ [#16]: https://github.com/jonallured/tinysky/pull/16
91
+ [#17]: https://github.com/jonallured/tinysky/pull/17
92
+ [#18]: https://github.com/jonallured/tinysky/pull/18
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.5"
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.5
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
@@ -28,16 +27,30 @@ dependencies:
28
27
  name: jwt
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - "~>"
30
+ - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '2'
32
+ version: '0'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - "~>"
37
+ - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '2'
39
+ version: '0'
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