Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

주의사항

가이드로 제공되는 아래 코드 중 파일 업로드 부분은 샘플 코드로서 보안 관련 처리가 미흡합니다.

파일 업로드 부분은 프로젝트 내부에서 사용하시는 부분을 그대로 사용하시고 아래 코드를 참고하셔서 연동 부분을 처리해주세요. 

1. 사전 정보

연동가이드의 예제는 아래와 같이 구성되어 있습니다.

  • 프로젝트 이름 이름 : synapeditor_django
  • 앱 이름 : edit

1.1. 앱 등록

# 프로젝트 settings.py
...
INSTALLED_APPS = [
	'edit.apps.EditConfig', #앱 등록
	...
]
...


# 프로젝트 urls.py
...
urlpatterns = [
	path('edit/', include('edit.urls')), # 앱에서 사용할 url 등록 
	...
]
...

2. 이미지, 동영상, 파일 업로드

업로드를 위해 아래와 같이 정의하였습니다. 경로나 API 형태는 변경하여 사용하세요.

  • 이미지 업로드 경로 :  media 
  • 이미지 업로드 API :  /edit/uploadFile

2.1. 에디터 설정

// 사이냅에디터 설정 객체
var SynapEditorConfig = {
	...
	'editor.upload.image.param': {
		'csrfmiddlewaretoken': '{{ csrf_token }}'
	},
	'editor.upload.image.api': '/edit/uploadFile',
	...
}

2.2. 업로드 경로 설정

# 프로젝트 settings.py
...
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
...

# 프로젝트 urls.py
...
urlpatterns = [
	...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...

2.3. url과 view 연동

# 앱 urls.py
from django.urls import path
from . import views

urlpatterns = [
	...
    path('uploadFile/', views.upload_file, name='upload_file'),
	...
]

2.4. view 생성

업로드 후 JSON 객체에 'uploadPath' 를 담아 응답해야 합니다.

# 앱 views.py
from django.http import JsonResponse
from .forms import UploadFileForm

# 파일을 업로드합니다.
def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        
        if form.is_valid():
            uploaded_file = form.save()
			data = {
				'uploadPath': uploaded_file.file.url
			}

    return JsonResponse(data)

2.5. form 생성

# 앱 forms.py
from .models import UploadFile
from django import forms

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = UploadFile
        fields = ('file', )

2.6. model 생성

# 앱 models.py
import uuid
from django.db import models

# 저장할 파일 이름을 반환합니다.
def get_file_name(instance, filename):
    ext = filename.split('.')[-1]
    return "%s.%s" % (uuid.uuid4(), ext)

class UploadFile(models.Model):
    file = models.FileField(upload_to=get_file_name)

3. HWP, Word, Excel 문서 임포트

문서 임포트위해 아래와 같이 정의하였습니다. 경로나 API는 수정하여 사용하시면 됩니다.

  • 문서 업로드는 media 디렉토리에 합니다.
  • 변환된 결과물은 media/output 디렉토리에 저장합니다.
  • 문서 임포트 API는 '/edit/importDoc'입니다. 

3.1. 에디터 설정

// 사이냅에디터 설정 객체
var SynapEditorConfig = {
	...
	'editor.import.param': {
		'csrfmiddlewaretoken': '{{ csrf_token }}'
	},
	'editor.import.api': '/edit/importDoc/',
	...
}

3.2. 업로드 경로 설정

# 프로젝트 settings.py
...
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
...

# 프로젝트 urls.py
...
urlpatterns = [
	...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...

3.3. url과 view 연동

# 앱 urls.py
from django.urls import path
from . import views

urlpatterns = [
	...
    path('importDoc/', views.import_doc, name='import_doc'),
	...
]

3.4. view 생성

임포트 후 JSON 객체에 'serializedData'와 'importPath' 를 담아 응답해야 합니다.

# 앱 views.py
import os
import subprocess
import zipfile
import zlib
from django.conf import settings
from subprocess import call
from django.http import JsonResponse
from .forms import UploadFileForm

PROJECT_PATH = os.path.abspath(os.path.dirname(__name__)) # 프로젝트의 절대경로
MEDIA_ROOT = settings.MEDIA_ROOT # 파일이 업로드 되는 절대경로
# 문서를 임포트 합니다.
def import_doc(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)

        if form.is_valid():
            uploaded_file = form.save()

			# 1. 문서 변환
            result = execute_converter(uploaded_file.file)
            
            if result['resultCode'] == 0:
                output_path = result['outputPath']
				# 2. 변환된 결과물 압축 해제
                unzip_path = unzip(output_path)
                pb_path = unzip_path + '/document.pb'

				# 3. PB 데이터 직렬화
                serialized_data = serialize_pb(pb_path)
                common_prefix = os.path.commonprefix([output_path, PROJECT_PATH])
                import_path = '/' + os.path.relpath(unzip_path, common_prefix)
            
            data = {
                'serializedData': serialized_data, # serialized된 pb 데이터
                'importPath': import_path # 변환 결과물이 저장된 경로(브라우저에서 접근 가능한 경로여야 함)
            }

    return JsonResponse(data)

# 변환모듈을 실행하여 문서를 변환합니다.
def execute_converter(file):
    fname, ext = os.path.splitext(file.name)
    module_path = '{0}/sedocConverter/sedocConverter_exe'.format(PROJECT_PATH)
    font_path = '{0}/sedocConverter/fonts'.format(PROJECT_PATH)
    input_path = file.path
    output_path = '{0}/output/{1}.zip'.format(MEDIA_ROOT, os.path.basename(fname))
    temp_path = '{0}/temp'.format(PROJECT_PATH)
	args = [module_path, '-z', '-f', font_path, input_path, output_path, temp_path]
	result_code = None

	process = subprocess.Popen(args)
	try:
		result_code = process.wait(timeout=20) # 변환이 20초 안에 완료되지 않으면 프로세스 종료
    except subprocess.TimeoutExpired:
        process.kill()


    return {
		'resultCode': result_code, 
		'outputPath': output_path
	}

#변환된 파일의 압축을 해제합니다.
def unzip(zipFilePath):
    unzip_path, ext = os.path.splitext(zipFilePath)
    zip = zipfile.ZipFile(zipFilePath)
    zip.extractall(unzip_path)

    return unzip_path

# pb파일을 읽어 serialize하여 반환합니다.
def serialize_pb(pbFilePath):
    serialized_data = []
    pb_file = open(pbFilePath, 'rb')
    pb_file.seek(16)
    pb_contents= pb_file.read()
    decompressed = zlib.decompress(pb_contents)
    
	for byte in decompressed:
        serialized_data.append(byte & 0xFF)

    pb_file.close()
    
	return serialized_data

3.5. form 생성

# 앱 forms.py
from .models import UploadFile
from django import forms

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = UploadFile
        fields = ('file', )

3.6. model 생성

# 앱 models.py
import uuid
from django.db import models

# 저장할 파일 이름을 반환합니다.
def get_file_name(instance, filename):
    ext = filename.split('.')[-1]
    return "%s.%s" % (uuid.uuid4(), ext)

class UploadFile(models.Model):
    file = models.FileField(upload_to=get_file_name)
  • No labels