Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

受付時にエントリーシートを印刷する機能を追加 #2447

Merged
merged 12 commits into from
Nov 24, 2024
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
17 changes: 9 additions & 8 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Run Trivy vulnerability scanner in fs mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
exit-code: '0'
ignore-unfixed: true
severity: 'CRITICAL,HIGH'
# vulnerability DBのダウンロードにしょっちゅう失敗するのでしばらく無効にする
# - name: Run Trivy vulnerability scanner in fs mode
# uses: aquasecurity/trivy-action@master
# with:
# scan-type: 'fs'
# scan-ref: '.'
# exit-code: '0'
# ignore-unfixed: true
# severity: 'CRITICAL,HIGH'
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ gem 'acts_as_list'

# PDF tool
gem 'ferrum'

gem 'printnode'
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ GEM
pluginator (1.5.0)
pre-commit (0.39.0)
pluginator (~> 1.5)
printnode (1.0.7)
prometheus-client (4.0.0)
pry (0.14.1)
coderay (~> 1.1)
Expand Down Expand Up @@ -725,6 +726,7 @@ DEPENDENCIES
opentelemetry-instrumentation-all
opentelemetry-sdk
pre-commit
printnode
prometheus-client (~> 4.0.0)
pry-rails
psych (< 6)
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/api/v1/check_in_conferences_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Api::V1::CheckInConferencesController < ApplicationController
include SecuredPublicApi
include SecuredAdminApi
before_action :set_profile

skip_before_action :verify_authenticity_token
Expand All @@ -13,7 +13,7 @@ def create
check_in_timestamp = Time.zone.at(@params[:checkInTimestamp])
@check_in = CheckInConference.new(profile: attendee, conference:, check_in_timestamp:, scanner_profile_id: @profile.id)
conference = Conference.find_by(abbr: @params[:eventAbbr])
GenerateEntrysheetJob.perform_later(conference.id, attendee.id, speaker&.id)
GenerateEntrysheetJob.perform_later(conference.id, attendee.id, speaker&.id, @params[:printerId])

if @check_in.save
render(json: @check_in, status: :created)
Expand All @@ -24,6 +24,6 @@ def create

def check_in_conferences_params(params)
json_params = ActionController::Parameters.new(params)
json_params.permit(:profileId, :eventAbbr, :checkInTimestamp)
json_params.permit(:profileId, :eventAbbr, :checkInTimestamp, :printerId)
end
end
2 changes: 1 addition & 1 deletion app/controllers/api/v1/check_in_talks_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Api::V1::CheckInTalksController < ApplicationController
include SecuredPublicApi
include SecuredAdminApi
before_action :set_profile

skip_before_action :verify_authenticity_token
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/api/v1/print_node_printers_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Api::V1::PrintNodePrintersController < ApplicationController
include SecuredAdminApi
before_action :set_conference, :set_profile

skip_before_action :verify_authenticity_token

rescue_from Pundit::NotAuthorizedError, with: :not_authorized

def index
auth = PrintNode::Auth.new(ENV['PRINTNODE_API_KEY'])
client = PrintNode::Client.new(auth)
@printers = client.printers
end
end
63 changes: 63 additions & 0 deletions app/controllers/concerns/secured_admin_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

module SecuredAdminApi
extend ActiveSupport::Concern

included do
before_action :authenticate_request!, :is_admin?
end

private

def authenticate_request!
claim = verify_token
set_current_user_from_claim(claim[0])
rescue JWT::VerificationError, JWT::DecodeError
render(json: { errors: ['Not Authenticated'] }, status: :unauthorized)
end

def http_token
if request.headers['Authorization'].present?
request.headers['Authorization'].split.last
end
end

def verify_token
JsonWebToken.verify(http_token)
end

def set_current_user_from_claim(claim) # rubocop:disable Naming/AccessorMethodName
@current_user = {}
@current_user[:info] = {}
@current_user[:extra] = {}
@current_user[:extra][:raw_info] = claim
if claim['https://cloudnativedays.jp/userinfo'].present?
userinfo = claim['https://cloudnativedays.jp/userinfo']
@current_user[:info][:name] = userinfo['name']
@current_user[:info][:nickname] = userinfo['nickname']
@current_user[:info][:email] = userinfo['email']
@current_user[:info][:image] = userinfo['picture']
end
@current_user
end

def conference
@conference ||= Conference.find_by(abbr: params[:eventAbbr] || params[:event])
end

def set_conference
conference
end

def profile
@profile ||= Profile.find_by(email: @current_user[:info][:email], conference_id: conference.id)
end

def is_admin?
raise(Forbidden) unless admin?
end

def admin?
current_user[:extra][:raw_info]['https://cloudnativedays.jp/roles'].include?("#{conference.abbr.upcase}-Admin")
end
end
2 changes: 1 addition & 1 deletion app/controllers/entry_sheet_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def show
object = JSON.parse(decrypted)

@profile = Profile.find(object['profile_id'])
@speaker = Speaker.find(object['speaker_id'])
@speaker = object['speaker_id'].present? ? Speaker.find(object['speaker_id']) : nil
@conference = Conference.find_by(abbr: params[:event])

# 全てのテーブルの行数を取得
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ def checkin
def view_qr
end

def entry_sheet
end

helper_method :profile_url

private
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/stylesheets/_entry_sheet.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
margin: 20px 0;
img.avatar-image{
margin: 0 auto;
width: 160px;
width: 130px;
}
}
}
Expand Down
27 changes: 26 additions & 1 deletion app/jobs/generate_entrysheet_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class GenerateEntrysheetJob < ApplicationJob
queue_as :default
# self.queue_adapter = :amazon_sqs

def perform(conference_id, profile_id, speaker_id = nil)
def perform(conference_id, profile_id, speaker_id = nil, printer_id = nil)
conference = Conference.find(conference_id)
obj = { profile_id:, speaker_id: }.to_json

Expand All @@ -19,5 +19,30 @@ def perform(conference_id, profile_id, speaker_id = nil)
)

page.quit

auth = PrintNode::Auth.new(ENV['PRINTNODE_API_KEY'])
client = PrintNode::Client.new(auth)

unless printer_id
printers = client.printers
printer_id = printers[0].id
end

pdf_content = File.read(pdf_file)
pdf_base64 = Base64.strict_encode64(pdf_content)

profile = Profile.find(profile_id)

job = PrintNode::PrintJob.new(
printer_id,
"#{profile.email} エントリーシート",
'pdf_base64',
pdf_base64,
'Dreamkast'
)

response = client.create_printjob(job)

puts("印刷ジョブID: #{response}")
end
end
46 changes: 46 additions & 0 deletions app/models/print_node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class PrintNode
include ActiveModel::Model

def initialize
auth = PrintNode::Auth.new(ENV['PRINTNODE_API_KEY'])
@client = PrintNode::Client.new(auth)
end

def printers
@client.printers
end

def print(file)
pdf_content = File.read(file)
pdf_base64 = Base64.strict_encode64(pdf_content)

profile = Profile.find(profile_id)

job = PrintNode::PrintJob.new(
printer_id,
"#{profile.email} エントリーシート",
'pdf_base64',
pdf_base64,
'Dreamkast'
)

client.create_printjob(job)
end

def url_qrcode_image
Base64.strict_encode64(RQRCode::QRCode.new([{ data: url, mode: :byte_8bit }]).as_png(size: 300).to_s)
end

def h1_text
case @stamp_rally_check_point.type
when StampRallyCheckPoint.name
'スタンプラリーチェックポイント'
when StampRallyCheckPointBooth.name
'スタンプラリーチェックポイント(ブース)'
when StampRallyCheckPointFinish.name
'スタンプラリーチェックポイント(ゴール)'
else
raise(NotImplementedError)
end
end
end
5 changes: 5 additions & 0 deletions app/models/qr_code_for_stamp_rally.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ def url
Rails.application.routes.url_helpers.new_stamp_rally_check_in_url(
event: event.abbr,
params: { stamp_rally_check_point_id: stamp_rally_check_point.id },
protocol:,
host: Rails.application.default_url_options[:host]
)
end

def protocol
Rails.env.production? ? 'https' : 'http'
end

def url_qrcode_image
Base64.strict_encode64(RQRCode::QRCode.new([{ data: url, mode: :byte_8bit }]).as_png(size: 300).to_s)
end
Expand Down
4 changes: 4 additions & 0 deletions app/views/api/v1/print_node_printers/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
json.array!(@printers) do |printer|
json.id(printer.id)
json.name(printer.name)
end
2 changes: 1 addition & 1 deletion app/views/attendee_dashboards/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
<% if @profile.attend_offline? %>
<!-- TODO: CNDW2024参加証できたら有効化
<div class="card-text">当日の参加受付には参加証の印刷が必要となっております</div>
<div class="card-text">参加証は <%= link_to 'こちら', profiles_entry_sheet_path %> から印刷してお持ちください</div>
<div class="card-text">参加証は <%= link_to 'こちら', entry_sheet_path %> から印刷してお持ちください</div>
<div class="card-text">スマートフォンで受け付け用の二次元バーコードを表示する場合は <%= link_to 'こちら', profiles_view_qr_path %></div>
-->
<% end %>
Expand Down
3 changes: 0 additions & 3 deletions app/views/profiles/partial_entry_sheet/_bottom_cell.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
<div class="a8 bottom">
<div class="floor_map">
<%= image_tag "#{@conference.abbr}/floor_map.png" %>
</div>
</div>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
resources :debug, only: [:index]
resources :check_in_conferences, only: [:create], path: 'check_in_events'
resources :check_in_talks, only: [:create]
resources :print_node_printers, only: [:index]
namespace 'talks' do
get ':id/video_registration' => 'video_registration#show'
put ':id/video_registration' => 'video_registration#update'
Expand Down Expand Up @@ -159,6 +160,7 @@
get 'profiles/edit', to: 'profiles#edit'
get 'profiles/checkin', to: 'profiles#checkin'
get 'profiles/view_qr' => 'profiles#view_qr'
get 'profiles/entry_sheet' => 'profiles#entry_sheet'
resources :public_profiles


Expand Down
30 changes: 29 additions & 1 deletion schemas/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,26 @@ paths:
$ref: '#/components/schemas/Sponsor'
'400':
description: Invalid params supplied

/api/v1/print_node_printers:
get:
tags:
- PrintNodePrinter
parameters:
- name: eventAbbr
in: query
description: abbr of event (e.g. cndt2020)
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PrintNodePrinter'
components:
schemas:
Profile:
Expand Down Expand Up @@ -991,6 +1010,8 @@ components:
type: string
checkInTimestamp:
type: number
printerId:
type: string
required:
- profileId
- eventAbbr
Expand All @@ -1011,3 +1032,10 @@ components:
- profileId
- talkId
- checkInTimestamp
PrintNodePrinter:
type: object
properties:
id:
type: string
name:
type: string
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def claim
def alice_claim
[JSON.parse('{
"https://cloudnativedays.jp/roles": [
"CNDT2020-Admin",
"CNDT2022-Admin"
],
"https://cloudnativedays.jp/userinfo": {
Expand Down
Loading