Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ on:
push:
branches:
- main

pull_request:

jobs:
build:
runs-on: ubuntu-latest
name: Ruby ${{ matrix.ruby }}

strategy:
matrix:
ruby:
Expand All @@ -20,10 +20,21 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false

# 👇 ESTE STEP FALTABA
- name: Install system dependencies (GD)
run: |
sudo apt update
sudo apt install -y \
libgd-dev \
pkg-config \
build-essential

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- name: Run the default task
run: bundle exec rake
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ source "https://rubygems.org"
gemspec

gem "irb"
gem "pry"
gem "rake", "~> 13.0"

gem "rspec", "~> 3.0"
Expand Down
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ PATH
remote: .
specs:
imprint (0.1.0)
ruby-libgd

GEM
remote: https://rubygems.org/
specs:
ast (2.4.3)
coderay (1.1.3)
date (3.5.1)
diff-lcs (1.6.2)
erb (6.0.1)
Expand All @@ -18,6 +20,7 @@ GEM
json (2.18.0)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
method_source (1.1.0)
parallel (1.27.0)
parser (3.3.10.1)
ast (~> 2.4.1)
Expand All @@ -26,6 +29,10 @@ GEM
prettyprint
prettyprint (0.2.0)
prism (1.8.0)
pry (0.16.0)
coderay (~> 1.1)
method_source (~> 1.0)
reline (>= 0.6.0)
psych (5.3.1)
date
stringio
Expand Down Expand Up @@ -66,6 +73,7 @@ GEM
rubocop-ast (1.49.0)
parser (>= 3.3.7.2)
prism (~> 1.7)
ruby-libgd (0.2.3)
ruby-progressbar (1.13.0)
stringio (3.2.0)
tsort (0.2.0)
Expand All @@ -80,12 +88,14 @@ PLATFORMS
DEPENDENCIES
imprint!
irb
pry
rake (~> 13.0)
rspec (~> 3.0)
rubocop (~> 1.21)

CHECKSUMS
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
Expand All @@ -95,11 +105,13 @@ CHECKSUMS
json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254
pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e
psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
Expand All @@ -114,6 +126,7 @@ CHECKSUMS
rspec-support (3.13.6) sha256=2e8de3702427eab064c9352fe74488cc12a1bfae887ad8b91cba480ec9f8afb2
rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273
rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
ruby-libgd (0.2.3) sha256=9ddf757d1abcc5d44166e30b3204b95579f561e2ed4f366ef2c5ffa6cc669c50
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
Expand Down
2 changes: 1 addition & 1 deletion imprint.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Gem::Specification.new do |spec|

# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"

spec.add_dependency 'ruby-libgd'
# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
end
12 changes: 12 additions & 0 deletions lib/imprint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

require 'imprint/version'
require 'imprint/signer'
require 'imprint/renderer'
require 'imprint/engine' if defined?(Rails)

module Imprint
def self.sign(source:, watermark:, expires_in:)
Expand All @@ -24,6 +26,16 @@ def self.verify(token)
payload
end

def self.render_from_token(token)
payload = verify(token)
return nil unless payload

Renderer.render(
source: payload['source'],
watermark: payload['watermark']
)
end

def self.secret_key
# sin engine todavía; Rails solo si existe
if defined?(Rails)
Expand Down
5 changes: 5 additions & 0 deletions lib/imprint/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

Imprint::Engine.routes.draw do
get 'render/:token', to: 'renders#show'
end
18 changes: 18 additions & 0 deletions lib/imprint/controllers/imprint/renders_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Imprint
class RendersController < ActionController::Base
def show
path = Imprint.render_from_token(params[:token])

return head :not_found unless path && File.exist?(path)

send_file(
path,
type: 'image/png',
disposition: 'inline',
cache_control: 'no-store'
)
end
end
end
9 changes: 9 additions & 0 deletions lib/imprint/engine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require 'rails'

module Imprint
class Engine < ::Rails::Engine
isolate_namespace Imprint
end
end
52 changes: 52 additions & 0 deletions lib/imprint/renderer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

require 'pry'
require 'gd'
require 'securerandom'
require 'tmpdir'

module Imprint
class Renderer
DEFAULT_FONT_SIZE = 24

def self.render(source:, watermark:)
raise ArgumentError, 'source image not found' unless File.exist?(source)

image = GD::Image.open(source)

apply_watermark(image, watermark)

output = File.join(
Dir.tmpdir,
"imprint-#{SecureRandom.hex(8)}.png"
)

image.save(output)
output
end

def self.apply_watermark(image, text)
color = GD::Color.rgba(0, 116, 139, 225)

raise "Font missing" unless File.exist?(default_font)

image.text(
text,
x: 20,
y: image.height - 20,
size: DEFAULT_FONT_SIZE,
color: color,
font: default_font
)
end

def self.default_font
@default_font ||= begin
font = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'
raise 'Font not found' unless File.exist?(font)

font
end
end
end
end
Binary file added spec/fixtures/sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spec/fixtures/source.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions spec/imprint_render_from_token_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require 'spec_helper'
require 'gd'

RSpec.describe Imprint do
before do
FileUtils.mkdir_p('spec/fixtures')

image = GD::Image.new(200, 100)
white = GD::Color.rgb(255, 255, 255)
image.fill(white)
image.save('spec/fixtures/source.png')
end

it 'renders image when token is valid' do
token = Imprint.sign(
source: 'spec/fixtures/source.png',
watermark: 'CONFIDENTIAL',
expires_in: 60
).split('/').last

output = Imprint.render_from_token(token)

expect(output).to be_a(String)
expect(File).to exist(output)
end

it 'returns nil for expired token' do
token = Imprint.sign(
source: 'spec/fixtures/source.png',
watermark: 'CONFIDENTIAL',
expires_in: -1
).split('/').last

expect(Imprint.render_from_token(token)).to be_nil
end
end
15 changes: 15 additions & 0 deletions spec/imprint_renderer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Imprint::Renderer do
it 'renders an image with watermark' do
output = described_class.render(
source: 'spec/fixtures/sample.png',
watermark: 'CONFIDENTIAL'
)

expect(File).to exist(output)
expect(File.size(output)).to be > 0
end
end