yiffspace-images 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f9025106d5bb94489dfd2d3e31ca2316b63d5fd9e388f32c865ba2dc894e3b4b
4
+ data.tar.gz: 95653c5d9dbcc6bfb928dec4a174dac3a927be8e31c458c164700b7b4e2171b5
5
+ SHA512:
6
+ metadata.gz: 5da48bdfab1e99c431abf2a0bbd52c953dce061389daf7bf5f98b054f05a34fe454bd4cbe320ce4affa25f917982c63824a08ae515dad14d9b58d0829663cbf4
7
+ data.tar.gz: ae7fa8214d9d0a8fba4b3da685e52b99788221e76ee9bbc49c2365e26b0fdc4abed4487d7dded070a8f974f10907a223f6fa6b9fe9f1a71e49855162b15e4a18
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## 0.0.1
2
+
3
+ - Initial release, extracted from the `yiffspace` gem's `YiffSpace::Images::*`,
4
+ `YiffSpace::Serializers::Avatar/BannerSerializer`, and
5
+ `YiffSpace::Configuration#images`. `Configuration::Images` is now
6
+ `YiffSpace::Images::Configuration`.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Donovan_DMC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # YiffSpace::Images
2
+
3
+ Avatar/banner URL building and updating (Discord/Gravatar), for
4
+ https://yiff.space and related projects.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "yiffspace-images"
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ ```bash
17
+ $ bundle install
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```ruby
23
+ YiffSpace::Images::Avatar.default_for(user.id).url
24
+ YiffSpace::Images::Banner.get_for(user.id, :discord).url
25
+ ```
26
+
27
+ Configure via:
28
+
29
+ ```ruby
30
+ YiffSpace.configure do |config|
31
+ config.images.server_url = "https://images.example.com"
32
+ config.images.update_token = ENV["IMAGES_UPDATE_TOKEN"]
33
+ end
34
+ ```
35
+
36
+ ## Contributing
37
+
38
+ Go away
39
+
40
+ ## License
41
+
42
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("bundler/gem_tasks")
4
+
5
+ # CI releases from an already-tagged, already-pushed commit checked out at a detached HEAD, so
6
+ # the default release task's git tag/push step has nothing to do and fails trying to push a
7
+ # branch ref that does not exist in that checkout.
8
+ Rake::Task["release"].clear
9
+ task("release" => "release:rubygem_push")
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ module Avatar
6
+ class Base
7
+ def self.type = nil
8
+
9
+ attr_reader(:id, :type)
10
+
11
+ def initialize(id, type)
12
+ @id = id
13
+ @type = type
14
+ end
15
+
16
+ def url
17
+ raise(NotImplementedError)
18
+ end
19
+
20
+ def update(*)
21
+ raise(NotImplementedError)
22
+ end
23
+
24
+ def serializable_hash(*)
25
+ { "id" => @id, "type" => @type }
26
+ end
27
+
28
+ def self.from_json(data)
29
+ raise(ArgumentError, "invalid data") if data.blank?
30
+
31
+ data = JSON.parse(data) if data.is_a?(String)
32
+ data = ::YiffSpace::Utils::OpenHash.from(data)
33
+
34
+ return Avatar.find_type(data.type).from_json(data) if self == Base
35
+
36
+ new(data.id)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("httparty")
4
+
5
+ module YiffSpace
6
+ module Images
7
+ module Avatar
8
+ class Discord < Base
9
+ def self.type = :discord
10
+
11
+ def initialize(id)
12
+ super(id, self.class.type)
13
+ end
14
+
15
+ def url
16
+ "#{YiffSpace.config.images.server_url}/avatar/discord/#{id}"
17
+ end
18
+
19
+ def update(hash)
20
+ raise(StandardError, "images.update_token config option must be set to use avatar update") if YiffSpace.config.images.update_token.blank?
21
+
22
+ response = HTTParty.post("#{YiffSpace.config.images.server_url}/avatar/discord/update/#{id}",
23
+ YiffSpace.config.images.httparty_options.deep_merge(
24
+ headers: {
25
+ "Authorization" => "Bearer #{YiffSpace.config.images.update_token}",
26
+ "Content-Type" => "application/json",
27
+ },
28
+ body: { hash: hash }.to_json,
29
+ ))
30
+ Rails.logger.error("avatar update failed: #{response.to_json}") unless response.key?("updated")
31
+
32
+ response.fetch("updated", false)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("httparty")
4
+
5
+ module YiffSpace
6
+ module Images
7
+ module Avatar
8
+ class Gravatar < Base
9
+ def self.type = :gravatar
10
+
11
+ def initialize(id)
12
+ super(id, self.class.type)
13
+ end
14
+
15
+ def url
16
+ "#{YiffSpace.config.images.server_url}/avatar/gravatar/#{id}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ module Avatar
6
+ module_function
7
+
8
+ def default_for(id)
9
+ type = YiffSpace.config.images.default_avatar_type
10
+ get_for(id, type)
11
+ end
12
+
13
+ def get_for(id, type)
14
+ klass = find_type(type)
15
+ raise(StandardError, "No avatar class for type: #{type}") if klass.nil?
16
+
17
+ klass.new(id)
18
+ end
19
+
20
+ def find_type(type)
21
+ constants.map { |c| [c, const_get(c)] }.find do |_const, value|
22
+ next unless value < Base
23
+
24
+ value.try(:type)&.to_sym == type.to_sym
25
+ end&.second
26
+ end
27
+
28
+ def find_type!(type)
29
+ find_type(type) || raise(StandardError, "No avatar class for type: #{type}")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ module Banner
6
+ class Base
7
+ def self.type = nil
8
+
9
+ attr_reader(:id, :type)
10
+
11
+ def initialize(id, type)
12
+ @id = id
13
+ @type = type
14
+ end
15
+
16
+ def url
17
+ raise(NotImplementedError)
18
+ end
19
+
20
+ def update(*)
21
+ raise(NotImplementedError)
22
+ end
23
+
24
+ def serializable_hash(*)
25
+ { "id" => @id, "type" => @type }
26
+ end
27
+
28
+ def self.from_json(data)
29
+ raise(ArgumentError, "invalid data") if data.blank?
30
+
31
+ data = JSON.parse(data) if data.is_a?(String)
32
+ data = ::YiffSpace::Utils::OpenHash.from(data)
33
+
34
+ return Banner.find_type(data.type).from_json(data) if self == Base
35
+
36
+ new(data.id)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("httparty")
4
+
5
+ module YiffSpace
6
+ module Images
7
+ module Banner
8
+ class Discord < Base
9
+ def self.type = :discord
10
+
11
+ def initialize(id)
12
+ super(id, self.class.type)
13
+ end
14
+
15
+ def url
16
+ "#{YiffSpace.config.images.server_url}/banner/discord/#{id}"
17
+ end
18
+
19
+ def update(hash)
20
+ raise(StandardError, "images.update_token config option must be set to use banner update") if YiffSpace.config.images.update_token.blank?
21
+
22
+ response = HTTParty.post("#{YiffSpace.config.images.server_url}/banner/discord/update/#{id}",
23
+ YiffSpace.config.images.httparty_options.deep_merge(
24
+ headers: {
25
+ "Authorization" => "Bearer #{YiffSpace.config.images.update_token}",
26
+ "Content-Type" => "application/json",
27
+ },
28
+ body: { hash: hash }.to_json,
29
+ ))
30
+ Rails.logger.error("banner update failed: #{response.to_json}") unless response.key?("updated")
31
+
32
+ response.fetch("updated", false)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ module Banner
6
+ module_function
7
+
8
+ def default_for(id)
9
+ type = YiffSpace.config.images.default_banner_type
10
+ get_for(id, type)
11
+ end
12
+
13
+ def get_for(id, type)
14
+ klass = find_type(type)
15
+ raise(StandardError, "No banner class for type: #{type}") if klass.nil?
16
+
17
+ klass.new(id)
18
+ end
19
+
20
+ def find_type(type)
21
+ constants.map { |c| [c, const_get(c)] }.find do |_const, value|
22
+ next unless value < Base
23
+
24
+ value.try(:type)&.to_sym == type.to_sym
25
+ end&.second
26
+ end
27
+
28
+ def find_type!(type)
29
+ find_type(type) || raise(StandardError, "No banner class for type: #{type}")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ class Configuration
6
+ attr_accessor(:server_url, :update_token, :default_avatar_type, :default_banner_type, :httparty_options)
7
+
8
+ def initialize
9
+ @server_url = "https://images.yiff.space"
10
+ @default_avatar_type = :discord
11
+ @default_banner_type = :discord
12
+ @httparty_options = {
13
+ timeout: 10,
14
+ open_timeout: 5,
15
+ headers: {
16
+ "User-Agent" => "YiffSpaceRuby/#{YiffSpace::Images::VERSION} (https://yiff.space)",
17
+ },
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("rails")
4
+
5
+ module YiffSpace
6
+ module Images
7
+ # No app/ of its own - this exists to register the Avatar/BannerSerializer with ActiveJob.
8
+ class Engine < ::Rails::Engine
9
+ config.root = File.expand_path("../../..", __dir__)
10
+
11
+ initializer("yiffspace.images.serializers") do
12
+ ActiveSupport.on_load(:active_job) do
13
+ ActiveJob::Serializers.add_serializers(
14
+ Serializers::AvatarSerializer,
15
+ Serializers::BannerSerializer,
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YiffSpace
4
+ module Images
5
+ VERSION = "0.0.1"
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("yiffspace/core")
4
+ require("zeitwerk")
5
+
6
+ module YiffSpace
7
+ module Images
8
+ end
9
+
10
+ class Configuration
11
+ def images
12
+ @images ||= Images::Configuration.new
13
+ end
14
+ end
15
+ end
16
+
17
+ loader = Zeitwerk::Loader.for_gem_extension(YiffSpace)
18
+ loader.ignore("#{__dir__}/images/engine.rb")
19
+ loader.setup
20
+
21
+ # Require the engine eagerly so it registers with Rails before the host app's
22
+ # active_support.initialize_per_engine_zeitwerk_loaders initializer runs.
23
+ require_relative("images/engine") if defined?(Rails)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("active_job")
4
+
5
+ module YiffSpace
6
+ module Serializers
7
+ class AvatarSerializer < ActiveJob::Serializers::ObjectSerializer
8
+ def serialize(arg)
9
+ super(**arg.serializable_hash)
10
+ end
11
+
12
+ def deserialize(arg)
13
+ Images::Avatar::Base.from_json(arg)
14
+ end
15
+
16
+ def klass
17
+ Images::Avatar::Base
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("active_job")
4
+
5
+ module YiffSpace
6
+ module Serializers
7
+ class BannerSerializer < ActiveJob::Serializers::ObjectSerializer
8
+ def serialize(arg)
9
+ super(**arg.serializable_hash)
10
+ end
11
+
12
+ def deserialize(arg)
13
+ Images::Banner::Base.from_json(arg)
14
+ end
15
+
16
+ def klass
17
+ Images::Banner::Base
18
+ end
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yiffspace-images
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Donovan_DMC
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2026-09-04 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: httparty
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0.24'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0.24'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rails
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '7.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '7.1'
40
+ - !ruby/object:Gem::Dependency
41
+ name: yiffspace-core
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.2.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.2.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: zeitwerk
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '2.6'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '2.6'
68
+ description: Avatar/banner URL building and updating (Discord/Gravatar), for https://yiff.space
69
+ and related projects
70
+ email:
71
+ - hewwo@yiff.rocks
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - CHANGELOG.md
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - lib/yiffspace/images.rb
81
+ - lib/yiffspace/images/avatar.rb
82
+ - lib/yiffspace/images/avatar/base.rb
83
+ - lib/yiffspace/images/avatar/discord.rb
84
+ - lib/yiffspace/images/avatar/gravatar.rb
85
+ - lib/yiffspace/images/banner.rb
86
+ - lib/yiffspace/images/banner/base.rb
87
+ - lib/yiffspace/images/banner/discord.rb
88
+ - lib/yiffspace/images/configuration.rb
89
+ - lib/yiffspace/images/engine.rb
90
+ - lib/yiffspace/images/version.rb
91
+ - lib/yiffspace/serializers/avatar_serializer.rb
92
+ - lib/yiffspace/serializers/banner_serializer.rb
93
+ homepage: https://yiff.space
94
+ licenses:
95
+ - MIT
96
+ metadata:
97
+ allowed_push_host: https://rubygems.org
98
+ homepage_uri: https://yiff.space
99
+ source_code_uri: https://github.com/YiffSpace/Gem/tree/master/yiffspace-images
100
+ changelog_uri: https://github.com/YiffSpace/Gem/blob/master/yiffspace-images/CHANGELOG.md
101
+ rubygems_mfa_required: 'true'
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 3.4.1
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 3.6.2
117
+ specification_version: 4
118
+ summary: Avatar/banner URL building and updating (Discord/Gravatar), for https://yiff.space
119
+ and related projects
120
+ test_files: []