Ruby on Rails 예제
주의
서버 보안을 위해 파일 업로드 및 문서 임포트 처리를 구현할 때 아래 가이드를 참고합니다.
아래 예제는 Ruby 2.5.1 및 Rails 5.2.3을 기준으로 작성되었습니다.
carrierwave gem은 파일 업로드를 위한 업로더로 사용됩니다. 설정 방법은 carrierwave 설치 가이드를 참고합니다.
이 예제에서는 /upload를 이미지, video, 파일 업로드를 위한 API로 사용하고, /import를 문서 임포트를 위한 API로 사용합니다.
// synapeditor.config.js
{
'editor.import.api': '/import',
'editor.upload.image.api': '/upload',
'editor.upload.video.api': '/upload',
'editor.upload.file.api': '/upload'
}
1. 파일 업로더 만들기
주의
아래 샘플 코드의 파일 업로드 부분은 의도적으로 최소화되어 있으며, 적절한 보안 처리가 적용되어 있지 않습니다.
파일 업로드는 프로젝트에 이미 구현된 기능을 사용하고, 아래 코드는 에디터 연동 부분만 참고합니다.
rails generate uploader File
# ./app/uploaders/file_uploader.rb
class FileUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
'uploads/'
end
def filename
"#{secure_token}.#{file.extension}" if original_filename.present?
end
protected
def secure_token
var = :"@#{mounted_as}_secure_token"
model.instance_variable_get(var) || model.instance_variable_set(var, SecureRandom.uuid)
end
end
2. 모델 생성
rails generate model UploadFile
# ./app/models/upload_file.rb
class UploadFile < ApplicationRecord
mount_uploader :file, FileUploader
end
3. 컨트롤러 생성
rails generate controller UploadFile
# ./app/controllers/upload_file_controller.rb
class UploadFileController < ApplicationController
skip_before_action :verify_authenticity_token # csrf_token
def upload
uploaded = UploadFile.create(file: params[:file])
render json: { 'uploadPath': uploaded.file.url }
end
def import
root_path = Rails.root
uploaded = UploadFile.create(file: params[:file])
# 1. Document conversion
input_file_path = uploaded.file.path
input_file_name = File.basename(input_file_path)
output_dir_name = File.basename(input_file_name, File.extname(input_file_name))
converter_path = "%s/sedocConverter/sedocConverter_exe" % [root_path]
font_dir_path = "%s/fonts" % [root_path]
output_dir_path = "%s/public/output/%s" % [root_path, output_dir_name]
tmp_dir_path = "%s/tmp" % [root_path]
system("%s -pz -f %s %s %s %s" % [converter_path, font_dir_path, input_file_path, output_dir_path, tmp_dir_path])
# 2. Serialize .pb
pb_file_path = "%s/document.pb" % [output_dir_path]
a_file = File.open(pb_file_path, 'r')
a_serialized = []
if a_file
a_file.sysread(16)
a_file.each_byte do |byte|
a_serialized.push(byte & 0xFF)
end
end
# 3. Clean up
File.delete(input_file_path) if File.exist?(input_file_path)
File.delete(pb_file_path) if File.exist?(pb_file_path)
render json: {
'importPath': "/output/%s" % [File.basename(output_dir_path)],
'serializedData': a_serialized
}
end
end
4. 데이터베이스 마이그레이션
# Add a 'file' column on UploadFile
rails generate migration AddFileToUploadFile file:string
rake db:migrate
5. 라우트
# ./config/routes.rb
Rails.application.routes.draw do
post 'import' => 'upload_file#import'
post 'upload' => 'upload_file#upload'
end