44 lines
8.6 KiB
Python
44 lines
8.6 KiB
Python
IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0NCmZyb20gZG90ZW52IGltcG9ydCBsb2FkX2RvdGVudg0KbG9hZF9kb3RlbnYoKQ0KDQoiIiINCuq4gOuylyBMaWdodCB2Mi4wDQpGbGFzayDrnbzsmrDtjIUgKyDqs7XthrUg6riw64qlDQoiIiINCg0KaW1wb3J0IG9zDQppbXBvcnQgaW8NCmltcG9ydCB0ZW1wZmlsZQ0KaW1wb3J0IGpzb24NCmltcG9ydCBzaHV0aWwNCmZyb20gZGF0ZXRpbWUgaW1wb3J0IGRhdGV0aW1lDQpmcm9tIGZsYXNrIGltcG9ydCBGbGFzaywgcmVuZGVyX3RlbXBsYXRlLCByZXF1ZXN0LCBqc29uaWZ5LCBSZXNwb25zZSwgc2Vzc2lvbiwgc2VuZF9maWxlDQppbXBvcnQgcXVldWUNCmltcG9ydCB0aHJlYWRpbmcNCmZyb20gaGFuZGxlcnMudGVtcGxhdGUudGVtcGxhdGVfbWFuYWdlciBpbXBvcnQgVGVtcGxhdGVNYW5hZ2VyIA0KZnJvbSBwYXRobGliIGltcG9ydCBQYXRoDQpmcm9tIGRvbWFpbl9hcGkgaW1wb3J0IHJlZ2lzdGVyX2RvbWFpbl9yb3V0ZXMNCmZyb20gZGIgaW1wb3J0IGluaXRfZGINCg0KDQojIOusuOyEnCDsnKDtmJXrs4Qg7ZSE66Gc7IS47IScDQpmcm9tIGhhbmRsZXJzLnRlbXBsYXRlIGltcG9ydCBUZW1wbGF0ZVByb2Nlc3Nvcg0KZnJvbSBoYW5kbGVycy5icmllZmluZyBpbXBvcnQgQnJpZWZpbmdQcm9jZXNzb3INCmZyb20gaGFuZGxlcnMucmVwb3J0IGltcG9ydCBSZXBvcnRQcm9jZXNzb3INCmZyb20gaGFuZGxlcnMuZG9jLmN1c3RvbV9kb2NfdHlwZSBpbXBvcnQgQ3VzdG9tRG9jVHlwZVByb2Nlc3NvciANCmZyb20gaGFuZGxlcnMuZG9jLmRvY190eXBlX2FuYWx5emVyIGltcG9ydCBEb2NUeXBlQW5hbHl6ZXIgICAgICANCg0KYXBwID0gRmxhc2soX19uYW1lX18pDQphcHAuY29uZmlnWydNQVhfQ09OVEVOVF9MRU5HVEgnXSA9IDE2ICogMTAyNCAqIDEwMjQgICMgMTZNQiBtYXgNCmFwcC5jb25maWdbJ1NFQ1JFVF9LRVknXSA9IG9zLmVudmlyb24uZ2V0KCdTRUNSRVRfS0VZJywgJ2dldWxiZW90LWxpZ2h0LXNlY3JldC1rZXktdjInKQ0KcmVnaXN0ZXJfZG9tYWluX3JvdXRlcyhhcHApICANCmluaXRfZGIoKQ0KDQoNCiMgcHJvY2Vzc29ycyDrlJXshZTrhIjrpqzsl5Ag7LaU6rCADQp0ZW1wbGF0ZV9tZ3IgPSBUZW1wbGF0ZU1hbmFnZXIoKQ0KcHJvY2Vzc29ycyA9IHsNCiAgICAnYnJpZWZpbmcnOiBCcmllZmluZ1Byb2Nlc3NvcigpLA0KICAgICdyZXBvcnQnOiBSZXBvcnRQcm9jZXNzb3IoKSwNCiAgICAndGVtcGxhdGUpOiBUZW1wbGF0ZVByb2Nlc3NvcigpLA0KICAgICdjdXN0b20nOiBDdXN0b21Eb2NUeXBlUHJvY2Vzc29yKCkNCn0NCg0KRE9DX1RZUEVTX0RFRkFVTFQgPSBQYXRoKCd0ZW1wbGF0ZXMvZGVmYXVsdC9kb2NfdHlwZXMnKQ0KRE9DX1RZUEVTX1VTRVIgPSBQYXRoKCd0ZW1wbGF0ZXMvdXNlci9kb2NfdHlwZXMnKQ0KDQoNCiMgPT09PT09PT09PT09PT0g66mU7J24IO2OmOydtOyngCA9PT09PT09PT09PT09PQ0KQGFwcC5yb3V0ZSgnLycpDQpkZWYgaW5kZXgoKToNCiAgICAiIiLrqZTsnbgg7Y6Y7J207KeAIiIiDQogICAgcmV0dXJuIHJlbmRlcl90ZW1wbGF0ZSgnaW5kZXguaHRtbCcpDQoNCg0KQGFwcC5yb3V0ZSgnL2FwaS9kb2MtdHlwZXMnLCBtZXRob2RzPVsnR0VUJ10pDQpkZWYgZ2V0X2RvY190eXBlcygpOg0KICAgICIiIuusuOyEnCDsnKDtmJUg66qp66GdIOyhsO2ajCIiIg0KICAgIHRyeToNCiAgICAgICAgZG9jX3R5cGVzID0gW10NCiAgICAgICAgDQogICAgICAgICMgZGVmYXVsdCDtj7TrjZQg7Iqk7LqUDQogICAgICAgIGlmIERPQ19UWVBFU19ERUZBVUxULmV4aXN0cygpOg0KICAgICAgICAgICAgZm9yIGZvbGRlciBpbiBET0NfVFlQRVNfREVGQVVMVC5pdGVyZGlyKCk6DQogICAgICAgICAgICAgICAgaWYgZm9sZGVyLmlzX2RpcigpOg0KICAgICAgICAgICAgICAgICAgICBjb25maWdfZmlsZSA9IGZvbGRlciAvICdjb25maWcuanNvbicNCiAgICAgICAgICAgICAgICAgICAgaWYgY29uZmlnX2ZpbGUuZXhpc3RzKCk6DQogICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oY29uZmlnX2ZpbGUsICdyJywgZW5jb2Rpbmc9J3V0Zi04JykgYXMgZjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NfdHlwZXMuYXBwZW5kKGpzb24ubG9hZChmKSkNCiAgICAgICAgDQogICAgICAgICMgdXNlciDtj7TrjZQg7Iqk7LqUDQogICAgICAgIGlmIERPQ19UWVBFU19VU0VSLmV4aXN0cygpOg0KICAgICAgICAgICAgZm9yIGZvbGRlciBpbiBET0NfVFlQRVNfVVNFUi5pdGVyZGlyKCk6DQogICAgICAgICAgICAgICAgaWYgZm9sZGVyLmlzX2RpcigpOg0KICAgICAgICAgICAgICAgICAgICBjb25maWdfZmlsZSA9IGZvbGRlciAvICdjb25maWcuanNvbicNCiAgICAgICAgICAgICAgICAgICAgaWYgY29uZmlnX2ZpbGUuZXhpc3RzKCk6DQogICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oY29uZmlnX2ZpbGUsICdyJywgZW5jb2Rpbmc9J3V0Zi04JykgYXMgZjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NfdHlwZXMuYXBwZW5kKGpzb24ubG9hZChmKSkNCiAgICAgICAgDQogICAgICAgICMgb3JkZXIg4oaSIGlzRGVmYXVsdCDsiJwg7KCV66CsDQogICAgICAgIGRvY190eXBlcy5zb3J0KGtleT1sYW1iZGEgeDogKHguZ2V0KCdvcmRlcicsIDk5OSksIG5vdCB4LmdldCgnaXNEZWZhdWx0JywgRmFsc2UpKSkNCiAgICAgICAgDQogICAgICAgIHJldHVybiBqc29uaWZ5KGRvY190eXBlcykNCiAgICAgICAgDQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOg0KICAgICAgICBpbXBvcnQgdHJhY2ViYWNrDQogICAgICAgIHJldHVybiBqc29uaWZ5KHsnZXJyb3InOiBzdHIoZSksICd0cmFjZSc6IHRyYWNlYmFjay5mb3JtYXRfZXhjKCl9KSwgNTAwDQoNCg0KQGFwcC5yb3V0ZSgnL2FwaS9kb2MtdHlwZXMnLCBtZXRob2RzPVsnUE9TVCddKQ0KZGVmIGFkZF9kb2NfdHlwZSgpOg0KICAgICIiIuusuOyEnCDsnKDtmJUg7LaU6rCAICjrtoTshJ0g6rKw6rO8IOyggOyepSkiIiINCiAgICB0cnk6DQogICAgICAgIGRhdGEgPSByZXF1ZXN0LmdldF9qc29uKCkNCiAgICAgICAgDQogICAgICAgIGlmIG5vdCBkYXRhOg0KICAgICAgICAgICAgcmV0dXJuIGpzb25pZnkoeydlcnJvcic6ICdKU09OIOuNsOydtO2EsOqwgCDtlYTsmpTtlanri4jri6QnfSksIDQwMA0KICAgICAgICANCiAgICAgICAgIyB1c2VyIO2PtOuNlCDsg53shLENCiAgICAgICAgRE9DX1RZUEVTX1VTRVIubWtkaXIocGFyZW50cz1UcnVlLCBleGlzdF9vaz1UcnVlKQ0KICAgICAgICANCiAgICAgICAgdHlwZV9pZCA9IGRhdGEuZ2V0KCdpZCcpDQogICAgICAgIGlmIG5vdCB0eXBlX2lkOg0KICAgICAgICAgICAgaW1wb3J0IHRpbWUNCiAgICAgICAgICAgIHR5cGVfaWQgPSBmInVzZXJfe2ludCh0aW1lLnRpbWUoKSl9Ig0KICAgICAgICAgICAgZGF0YVsnaWQnXSA9IHR5cGVfaWQNCiAgICAgICAgDQogICAgICAgIGZvbGRlcl9wYXRoID0gRE9DX1RZUEVTX1VTRVIgLyB0eXBlX2lkDQogICAgICAgIGZvbGRlcl9wYXRoLm1rZGlyKHBhcmVudHM9VHJ1ZSwgZXhpc3Rfb2s9VHJ1ZSkNCiAgICAgICAgDQogICAgICAgICMgY29uZmlnLmpzb24g7KCA7J6lDQogICAgICAgIHdpdGggb3Blbihmb2xkZXJfcGF0aCAvICdjb25maWcuanNvbicsICd3JywgZW5jb2Rpbmc9J3V0Zi04JykgYXMgZjoNCiAgICAgICAgICAgIGpzb24uZHVtcChkYXRhLCBmLCBlbnN1cmVfYXNjaWk9RmFsc2UsIGluZGVudD0yKQ0KICAgICAgICANCiAgICAgICAgcmV0dXJuIGpzb25pZnkoZGF0YSkNCiAgICAgICAgDQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOg0KICAgICAgICBpbXBvcnQgdHJhY2ViYWNrDQogICAgICAgIHJldHVybiBqc29uaWZ5KHsnZXJyb3InOiBzdHIoZSksICd0cmFjZSc6IHRyYWNlYmFjay5mb3JtYXRfZXhjKCl9KSwgNTAwDQoNCg0KQGFwcC5yb3V0ZSgnL2FwaS9kb2MtdHlwZXMvPHR5cGVfaWQ+JywgbWV0aG9kcz1bJ0RFTEVURSddKQ0KZGVmIGRlbGV0ZV9kb2NfdHlwZSh0eXBlX2lkKToNCiAgICAiIiLrrLjshJwg7Jyg7ZiVIOyCreygnCIiIg0KICAgIHRyeToNCiAgICAgICAgZm9sZGVyX3BhdGggPSBET0NfVFlQRVNfVVNFUiAvIHR5cGVfaWQNCiAgICAgICAgDQogICAgICAgIGlmIG5vdCBmb2xkZXJfcGF0aC5leGlzdHMoKToNCiAgICAgICAgICAgIHJldHVybiBqc29uaWZ5KHsnZXJyb3InOiAn66y47IScIOycoO2YleydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpCd9KSwgNDA0DQogICAgICAgIA0KICAgICAgICBzaHV0aWwucm10cmVlKGZvbGRlcl9wYXRoKQ0KICAgICAgICByZXR1cm4ganNvbmlmeSh7J3N1Y2Nlc3MnOiBUcnVlLCAnZGVsZXRlZCc6IHR5cGVfaWR9KQ0KICAgICAgICANCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6DQogICAgICAgIGltcG9ydCB0cmFjZWJhY2sNCiAgICAgICAgcmV0dXJuIGpzb25pZnkoeydlcnJvcic6IHN0cihlKSwgJ3RyYWNlJzogdHJhY2ViYWNrLmZvcm1hdF9leGMoKX0pLCA1MDANCg0KIyA9PT09PT09PT09PT09PSDtjIzsnbwg7JeF66Gc65OcIEFQSSA9PT09PT09PT09PT09PQ0KDQpAYXBwLnJvdXRlKCcvYXBpL3VwbG9hZC1maWxlcycsIG1ldGhvZHM9WydQT1NUJ10pDQpkZWYgdXBsb2FkX2ZpbGVzKCk6DQogICAgIiIi7YyM7J28IOyXheuhnOuTnCDihpIgL3RtcC97c2Vzc2lvbl9pZH0vaW5wdXQvIOyggOyepSkiIiINCiAgICB0cnk6DQogICAgICAgIGlucHV0X2RpciA9IGYnL3RtcC97c2Vzc2lvbl9pZH0vaW5wdXQnDQogICAgICAgIG9zLm1ha2VkaXJzKGlucHV0X2RpciwgZXhpc3Rfb2s9VHJ1ZSkNCiAgICAgICAgDQogICAgICAgIGZpbGVzID0gcmVxdWVzdC5maWxlcy5nZXRsaXN0KCdmaWxlcycpDQogICAgICAgIGlmIG5vdCBmaWxlczoNCiAgICAgICAgICAgIHJldHVybiBqc29uaWZ5KHsnZXJyb3InOiAn7YyM7J287J20IOyXhuyKteuLiOuLpCd9KSwgNDAwDQogICAgICAgIA0KICAgICAgICAjIOyEuOyFmCBJRCDsg53shLENCiAgICAgICAgaW1wb3J0IHV1aWQNCiAgICAgICAgc2Vzc2lvbl9pZCA9IHN0cih1dWlkLnV1aWQ0KCkpDQogICAgICAgIA0KICAgICAgICBzYXZlZCA9IFtdDQogICAgICAgIGZvciBmIGluIGZpbGVzOg0KICAgICAgICAgICAgaWYgZi5maWxlbmFtZToNCiAgICAgICAgICAgICAgICBzYXZlX3BhdGggPSBQYXRoKGlucHV0X2RpcikgLyBmLmZpbGVuYW1lDQogICAgICAgICAgICAgICAgZi5zYXZlKHNhdmVfcGF0aCkNCiAgICAgICAgICAgICAgICBzYXZlZC5hcHBlbmQoZi5maWxlbmFtZSkNCiAgICAgICAgDQogICAgICAgIHJldHVybiBqc29uaWZ5KHsnc3VjY2Vzcyc6IFRydWUsICdzZXNzaW9uX2lkJzogc2Vzc2lvbl9pZCwgJ3NhdmVkJzogc2F2ZWR9KQ0KICAgICAgICANCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6DQogICAgICAgIHJldHVybiBqc29uaWZ5KHsnZXJyb3InOiBzdHIoZSl9KSwgNTAwDQoNCg0KQGFwcC5yb3V0ZSgnL2FwaS9hbmFseXplLWRvYycsIG1ldGhvZHM9WydQT1NUJ10pDQpkZWYgYW5hbHl6ZV9kb2MoKToNCiAgICAiIiLrrLjshJwg7YOA7J20IOu2hO}{'session_id': session_id})
|
|
except Exception as e:
|
|
return jsonify({'error': str(e)}), 500
|
|
|
|
|
|
@app.route('/api/generate-report', methods=['POST'])
|
|
def generate_report():
|
|
"""문서 생성 (전체 프로세스)"""
|
|
try:
|
|
data = request.get_json()
|
|
session_id = data.get('session_id')
|
|
doc_type = data.get('doc_type', 'report')
|
|
|
|
if not session_id:
|
|
return jsonify({'error': 'session_id가 필요합니다.'}), 400
|
|
|
|
processor = processors.get(doc_type)
|
|
if not processor:
|
|
return jsonify({'error': f'지원하지 않는 문서 타입입니다: {doc_type}'}), 400
|
|
|
|
# 백그라운드 작업으로 실행하는 것이 좋으나, 여기서는 단순 구현을 위해 직접 실행
|
|
result = processor.process(session_id, data)
|
|
|
|
return jsonify(result)
|
|
except Exception as e:
|
|
import traceback
|
|
return jsonify({'error': str(e), 'trace': traceback.format_exc()}), 500
|
|
|
|
|
|
# === 정적 파일 서빙 ===
|
|
|
|
@app.route('/output/<path:filename>')
|
|
def serve_output(filename):
|
|
return send_file(os.path.join('output', filename))
|
|
|
|
@app.route('/static/<path:filename>')
|
|
def serve_static(filename):
|
|
return send_file(os.path.join('static', filename))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# DB 초기화 및 서버 실행
|
|
app.run(host='0.0.0.0', port=5000, debug=True)
|