From 90c242e46bb253c0b920c2cea64e009fe2cac757 Mon Sep 17 00:00:00 2001 From: "Kim.KANGHEE" Date: Mon, 13 Oct 2025 22:08:53 +0900 Subject: [PATCH] update --- .../__pycache__/utilities.cpython-313.pyc | Bin 10151 -> 15099 bytes .../routes/__pycache__/xml.cpython-313.pyc | Bin 6651 -> 8568 bytes backend/routes/xml.py | 115 +++++++--- data/logs/2025-10-05.log | 14 ++ data/logs/app.log | 217 +++++++++++++++++- 5 files changed, 298 insertions(+), 48 deletions(-) create mode 100644 data/logs/2025-10-05.log diff --git a/backend/routes/__pycache__/utilities.cpython-313.pyc b/backend/routes/__pycache__/utilities.cpython-313.pyc index b1e6bba2df04e1c72b7190e0cf770f1b6364d1c0..5f19d57d47c636d12f17ed9fce61bc25a6d57fa7 100644 GIT binary patch delta 3322 zcmZuzZ%|WL7QZhqFFf-9e*%Q$C4dq!paQO1z~X{H1)_PRtBo{92$G7x-XvAoodI|4 zZdcqvy|q#+yEtoI+;O(LxZQlPGrF~v&aBfgFbie*P~CoNV#U?n>C`WKZ^8rYcr!Wg z+;h*r`|dfv`~K*D7F9k`D5L<7M-P&nmx@j+%_2^8z3>#p^3oEDmu(iITa@|qEtB0K z2=;1uV>T!!MtBHMXvInergADR#!BWFDA^8(oLS@Z)Q2kSzv!gKiRnk0395FyU%OKz zRh1m-c{Aug&>KaSatrfMF#u=LDY+5-o<2|g52+Lz%wDlanU1iMdNk;&v|mOm-d*@PZb7AiB6mJMxH4Z36>ma8USFo-lIg< z6*-h(!=gtD2K_rXmvsPMLNddaoVsZO0G~z3#A8K|4F-c}9oJ#ml@RCE(?yG_NSf`IEr`pE=C|;3-5JwIM^9);c3G zi8cUqKiB5KnW?d?O=a>|UpP}*uUy&2CZU<16gTT(5lqniE!7WodU160yB&_UUO zZ)K1TB#1BNsbA-nJnw16R`lsL-mtt4Ax`sHI^J>&rzz^j8L){%c z+=E}8;ZibOgZ^+3h5}t&;^GCaZl{+^4pv`CT)vuo_a^u7t=}e3TzYsS#yvcFGC6XS zOOD(~48139fmzrqBnQ+dE{+_DKvD^1mLO=UELS4Zy#9aq|hW}v^enkV|sT>Vy zO~@f#jqYi43M4>pKDYVw=5t$5Z=KTR&*)r}I@egojIMlASN^5iydc&o8c|YPZ)%)q z`C`xKdnR_o^LJ0{_k5|hJe2^A2{q|*3tYh9Sf~JU&8hW+o9E@4xV|OseJ$SNi~Ia> z?Y{W_gVXXZ^hD|^Pc4?;Xp5~HKX|S6R$g4YeIj#O?s+N)a{W7X!;MpV=ag(sT)gJH zrv*Tt`vlN9{v%znzAAP!b}(*zWk$VYO14p)r%PnFd!Jh`iq);pQIS=HkDd}bmy z1B)i|87!J`(u7|tZ78HCHWoJI(Vyor4Ta8S z)A;_J1#w*?p28+VNLi!~yiai;8fy1Ot>uXJxwyOX?XK+L zZmATkry{mt>C(u=91Q^VWLF7^3dF)t^-6$aFjD+RCIEa_&@$3{D? z@-pbY(c$nio_xW_@>9520(rRX51Q}9?FaaGMhtu>e)g0NXw-LM&dL`{=g?~@=DNvEvw)BLTF6; z`-9+5fL~`;^lR*vAOMEEMG#7!zrqphOMzbDGB_@kkTdbYP41g(*OP;z56=#NGd{}I z9%&19B}a~P$^KuCB#&Qzc=k$S@a@FlrDCaz>*#@pxbDEAV5NgNBZcU1>*&AawL`*KkmeSaHaYqJ^mnxg=>{_xq4wR z9E@<-E1nR)u8w|;JzT{LlCF}%7d3}mNQv}Dp8~Prt1aJf}jA=n&^4fab~~{{FqaPLqYgv z5T*~iJp|`6Q^(#Lh;+`$!fi0r8}X+mblahJ*h%bP!X!-6XTR@BIzQ`T?HzOZp7r))B(Y|2joOW(%MJeliJdO9Sh=Irk?tW z)y%M#N!Bv_ld;2b!u{we3l!?1=HE2W%T=djQ*z6!+&Ik4%Cjz%4j+BLY9W(RN#CaN zMWMBvv!1ce%2l&Dwpoo~R%@JB>rT0+)cNR6PX3x%nP#YRsB&Je8*-m;$E`KDUcK9T zyY-ekZfTj8d%tECab;!f=rr4a-gUTCrPr$eR)4+z+LpMnYMR}ON-Xx)dTO3k4Jl42 z;%3)aV2qC&*H5z>=CP%EQ%n=1Hz-N^Ljb*>@1gdhZ}W?(11Pt^COM3~6i{ee zLD<2~N&WtgXe0`Qem}&34dz5W;dE`R$20gknkg8lswFJB|8VJYDETd8>C9Z(6c&jJ-NmPb|t)79}ezHZF+qbYVY*e!jZs|EYdjnE(I) delta 367 zcmexey4;`dGcPX}0}%Y*_aI||^h7=hrVWf6H6}1}m@l} zN=r(MQsd)`n1K?vnDUE@B7uw|Ll6-@`M5=cfHQ~*@>~(fuAdu$uWnV;n@$>l>NMTvS?ibdP9E&4(FAQ@a{*+Roe^s+3-A<=7Pn=Wzv`ZUy=dgY&sUPA`>gomTf| zd6=0iXV?KFC8^WI8CReksT<{r3!l<1hcme-&Rng6c9vz@6+NY0ZdSV@&Pv9%L}&3+ z+U9Zj&{~z&TEy9wZM~vb#625%q`40%JoU_fYvd*-M&blRa2bqD-mz90Jn zA<>NaKsS#)A-=EQ?+x*y7W3Z?^Fl~uG2iXOd{;=+hOyt%6U3sr$L|$RLq{fmu-6yx z5K$26h9{c(V4%m>E7Irs{9Wlql~$969DdYeClp3eJ91~&N+Jk#q+cOI@(Zz}UUZ9U zb*Mxu=6iiY2*!9y8MOwqcuw_$UfSE=FOVMX;`WA`&iY_C-|1^`*VTIt1$u&=zHaR8 z^7u&cl(*{)%(W8-!y#VigdUvz=fymwchY654(CIEIq(xKkPV`TjCO`u5o1=2SN$`y z`Y}913#Q1x18IscLjmlbYDc@Fw3n)YoFs20jPEH^=O|7kTQH|0TgXk8Y*CV}q=V>^ zl3OE}GFPIt969J#k#c@Q7RAAc8Z7kteIZfp51!>QHo{ZUT6g$x+w+YLp2p+H8e6$T zZLJ(ECEMfk^8s%kpIT3xM?{TYKWW(QA(i+Uc$5o2fs6+h#$Xz*xL7-5I5~Fitry>X zaZ-rX#mlN9-;I@3&y>~1%4*|fb@!f|X*?N&|FV-&<|MX3%jH*Z3TjSLqo_kMkaoo! z+=_vKP&)NdU%eWD4%9J9UfVt>EAL|kn4C`Tr=6;VcL2MI<>)+R@5_d$v@t*%_@xrZ z$n`w*3u~?p{}0sY6C)#uiHma=B8h*zZJ&E(IQhy&S8`%J`Nkc4;`UVX#&F{8_w32Y zWa9GV+~`>1)}7>q@lE!*(eX!9gRbQGMB?&L@^>SNAC24Ru3Sl8e=qT~SCiKV?T>yv zmAEpP_{q3E@vA$@pWK-ny#M*w3F_kuo)_DfhCJ7=N3`bby{R3!z3Nr?Sm=P)a~iz1N^yuyieRDcmuwW zZ-DpoV_x9#3%n;B@O1$gIQRI2U0%PieSgiZuvhM#=`HXJS3|Iwz}iBn_8-WY(w z=K|SbujJ-apqxS?^E2uzl|8oy2P+k0OJ1*uKddw_*1ue+oCFmy(y> zO&gJ@>GlSCc|2fFy#Wv5sMDc7KY+82ycmMPf<<%H4ig>$Th|f=q!rZzJWmt}soiEz*`#Tq zWni*(*T7GB5i+nt4KnAARL$g-$MVYKrnQ3y=T(flfts}xOlsdT-!e~ERL2VseN<6B zvGorpeskgv9Y5BLQEzF+HL;57SmB|#rFlsGghj@ZXvwB2bcd1EU zS#-cme_)~@A27JW{r;f0n=CK5L~YzLSYK@)A37cE7P_D(C6T3pMW7xJLJk(MR4hkF z?zH=>2tk3%*csrSY^TJE!2XvZa9N_;o=s4kilb#3vuBY|2k}v)l%XTpuFFve!B8nJ zuS=GEica<4q7!zwvM;_`Yk=w?Feasr0=eWal1rJZJkEA%GhjeKwGy?f+(6)qlbe9_ zqQtTAr>j;;&R5x@O1SMfJiXD1$}Bb?KkaHP?dq(D5DniPw+xY&_7tdglgfZ z)B_;}=&V)PAh*q2VHHg6^ix;CoIT<)2o(c#9o;&Vy7mADr_t2XDuEP%u`nPxN?v;v z{1)()=0+#d?o#qPcrX_x=3co@@b$tJ_(V=od)A8szCiC6R@m^)g)kN-d@AAdo1@7a zZxaXYr{F_n_naIWvnOv1WnfxTp5>l_w={M;5gAFmeP;=zj=v|ldh+-Z!(+*7 zSwj=GLb$67pgRmSnC>9cHH`CS;_a~-`=?~qsqVpF9E6G6lQ&;aR}+p(M8=b_hHqqb z?I^&6ym1X=BHhb}Qof5sAuOpNW-SE>l8=H(xR)U+OeQ31Qi~v}`_2%iVFd3B;1vlW zh%CEK_XWE}UE{efzMsUaq836-h%tLbhD2|o8e$jlm>7{E+$8B1b)>zg9~@ng;w8V$ z4k<-f`V7Wn4s??l3x5wQE>V>+@9N%*duI%#F+=ItiMV0Cm8i)8w&t zzJ2T4@x0wb>=Ql8wT(PCV_O%qt&3aMPgcY%+XfHKtBmRv>LHsu!xqKZq8WB&j9obq zigZUwY4=0ccvW{%H?n5f_ao;tyK0`Hb-53XwySLy+r}EFjjMrrb(X8fOU7uSW3pm$ zMbuU~&F+xKR)6=zG}{Jxjrk)7qorHo`CH?LZBb_1XHV86V*w%6o$2`&O|u6UPU0iB zity{sFP{`3OYvhw>2m+oXql(s`Xym%8)@D`&9dgJIhS&xMO!1QB6-n*9n)-8dSPHL z%`vw5OVUjX&~z)jgb(s;jSTuwUD*VAO>Sc)x@TAm<@?Nr#;x@IEfmQs^-UCgf1e7T zKR^_eA5b(YGy0~z^aIn{rd{-dU1}%~l(@QiKOf==nY;E7Tc{xhLZXFz3t|z4%bnmQ zjuKxKj3JdWVJ5JW;%9a!KBQam0Ob~$a|)T2fGHH_%aTeLWonRkUGWn*hEr!@wc;CR zF$66$jeIRnv6AAmF4YBWplBf6!)dmwvJtj}oNh?Tt?;h=L}Dy<31fZDkpXikVYf-GD7<)1^az8J!B0}(YtCecD#hHwIT=b2{; zn1_j9BZIjlo(1MH1g|Aj**yi2c5oq50W!}s8npzKhKq(PIUqS)JZy-T?1`H8 zPMx1-4-u3Ch#Y=#;{3#!sBPOcyM0+$T(bZcH&33MW_K-AmVw0;X$;)0K;Xv7y2UdTeq^eVb#)!Q`a1a z1J&11mKVGnj=6~gv?y^|zHxwVr`;us1mKp$3o<4zTd&X52N)?rSSIdhXE+0=#v|Rs`Xh)(nT1PwVGOXR^MdSnhs*cQsQjK z3%G)6x}2Po{9j}LYFTR<`_)-1TQ1jSuCTI}cJ-pDBeSx(OR!&Er*6Fg*bmoC)B*F# z)(h@@;IHe=`wG4J*?Ku`KqK)E(S3WdZb#t~-XUX=;{tM6`+F(kArZ>8A7mmFya&WY zZC5Z5f|x@@1F9UoNWp*3fI1xN*}Mw^5|$6Z`6zL)wE_MtKs}!!ouM%}9!>=!Te1`a z!z~U((vl0KkQ9X}bd?S;F5jHH0yKsjp+^UW{|+u0O1pOF(Nx5qOv^}7nM`Tvs=pSW z4CKgInL08{pRINhZMLt=ez+aPr8q~_qz;52-hlI4+yu|br!n|O*2RnZvl!0U;G5aG z&~p4J>M#$-OHws)J003otn@tT9MB8mC+s~d>Xnn>ZizWD8LL20l7umkQjrWR&kOsY z%1>n8k>Z%YjX$?Vo}Fg*E~GRP*=S8a{QgVdA1jD!%VtfstNx4r8Pm#`Y311Y$<=Yw z<{^4sg9?hTb-dm&Q81Yww>f8QRWVytBs6s_ZaXlfpJ!NI8}%onMT$$BBZYU%huUJs zgR>B89lmsUtah?`a$~f(YTCGS)|eZ$Hr(}18;{QBm5d*ZmhXy}R>$*dqQ;tey+&>O zleOTQ^L6Ls`eA3(x^2c<6SLM#Ro$(OTc4e=9*tR#M!(e_eZC`Z?HtlRF~XVQSZxHn zg`-jC=x0yrsc%5x8>Gla1tTZpJaXwswA2-$CWYvV?bF6eX`uCYkIxueW5!m(;UM@W zIdX^ChgRF3%KNo9m?&`^y&*iolzbfA04)wCAftKQJK zj=sN^BDq7~w3@!ZeQnb-^n+*AP=2shf6z`paIHUBLjO~V8p>(c3pYb=@M(_^g>gV+ zP6dPh>>B(XsFq~pPYgufQ6lO+o}MtY;XNJSMI}kI3{#Wc?Tw{TFJR zL2VzSbswYRf7e-ucZ^lUb!!GSf6-9XnkOtpd8j9>fwIh(A{G0?(w9o3rm{F?e@L1C ztkP1ok7=Z`kPIShxSh{WOAYl+^h_KdER9l5NwkdGu86wk8MvKqpp+grMtUNW@IDZJ qtjf<4uAOJ#cHXJTIwFlzRgqfKb-g5APJN3~`fi~9%#a7tO8hU|7s59H delta 3383 zcma)8T~J%c72dr+(!Ez#(nWtDB#=b-6aJCSj|t%!Gx!EiMGTev0JbT7EXDLY~Apq|I6{xTWgdu`{sxv(d zV#v()uwf2yx{d4M!vn2CSt{*QWp-0r$Zv* zNCYwyk(Gw~dPj~9^mZQ^%o=0KC>o0)q9pV}vz%V)r{alJkOVu(FL8;8X|QepR{O03 zEB4B?y)t8|nm(3eIKCUM25LX@ec)RT)Mu2gzXs~(J3op2A@<2R?3yjQ?YiYk2kK{d zP3c+}fb7vcyYKO7Q@h5sfBTIHiVnjUYbNh=z|cgBZH8YH%$lY7UhU@s{*`2@wsqEl z-<5P$ai56_m2QR@KC9xXtSjl_*(DBk@pwtvZ7O`d7YzPZ`Ug9D2VlRv+hixz>m%a8 zzbx@$(XQCa!4NZ8l6TMCX;x^$Efx>%H=FSn4$(fWf;ijBj>B=##`?fG3|jFOi;A19k9g!GX|ZN$6oXD= zBs!|atWu#+%xu8|1#qi!S?VN4Klvqofd8a)ri}L4?%REHeJjR_w6S8%UU9eaqqYy) zGWPv5!kVMxebzL*}EcFq~(f*#(R|-)jC#X z<>vA0$8VjUCq!75t8yG`cCIS!+txYjU4B`qCMYvIZuZ{j)jWF^&ZZWAqPd%w<(4(M zNV6ULv-`2Eu1i3)XqJxq?q#9pE0g`!G0nR#fQ$))KwAv;XbLmjeXe4Q2h|3dK*jhM?gB#!akC!jx@558hN5$a)rjC6VYUJ z(4l-AXg>`}=KSD^qI3S&#QGkH6nqid&~T{`D38!R)5j3V!)%WUfH)k2gZaK- zl}1|uAh?Eurp=~d+)cnp8Na#KLfUZyqcU3{j9BvCL4|^k2zHa`7q~fOzkCaN92_tXx@%yYNZIz8lo3tiDV*cn2Jxt;^z=Os?b3y=nfqJeEEdqYOAJJx#mA1AO9ZeBSI}Q0g5qg)Dm0N}t zC6HDE8B@iFBa6eCs&>-yrn^^-rfZk4UcPqa>XjU05Op&2T<>|ek05Y%cs8t+cWAcP z?+2IVUW!vfg87bx=7l=V-Sk*Ku!;MF_kO%A99t{keyjj|(L71eBp`23%k4VIJHAWMJ^W*HmlG^GrNb6>$yaq)WFLq;(Jwhd(Xm)^1G_j?T*+h^ zY!n**KR7x_e+rcrn+o6|XAyLGQxS!{Q6Gc0ytXx~TRJH}uEds~j} z7>YAG5em30L=}_1Phm`Ze55pQ9`sUxHiX+>L+5(YN8RW#>Vf z8pgRuRbinr%&A2!Y$XVQNO|5$+B@Y4yR8I2Eul;vVs~(4s{}Lti^I9Ue`llLk$3;A z^5SNTt$8bxb$bs`4RKCq963Jv-`<%$XzRx*Pwj4cgyz z@jcB!m=&V&)01Pd_!+$B376NCuqnzGa@p`dyF2~t&TstB-udv~?=H0ZQ3LMrj_*27 zyg~b`IExMw*9K8HNQs|%i&Krnn3XOda%CAwMlU8`MdGZ8qN8IQZUfEF>r_UhL4&L* z9=$NKS-DPYL`z7}7EHLEXSa}tJvvDo12p0w>B`d{dIS0&+{TM#2U4!G+Y@sWE3WFa ztNQLQ7ArEYrWsR?G3w``a&zGNzsm{!@G z@wQ~_t(x4LlX%{_YIEJ*JGXbCW_GV;tDiBh%j7;a-?2EHHVtUpzzb%*7^lk{$=%Z6 zYfKRwfF-30ITZ;ebYc022 zh@x|sqElz~P9b%gmN5t%rzH6sux|0!n9X|EvwM_ poRPQ1w&pnUm@6;DRxV5}jxS8o=ypB21fGC})E!@Q^jZH?{{bfx+#&z~ diff --git a/backend/routes/xml.py b/backend/routes/xml.py index a87bc3c..424a1a7 100644 --- a/backend/routes/xml.py +++ b/backend/routes/xml.py @@ -1,9 +1,10 @@ from __future__ import annotations import logging +import unicodedata from pathlib import Path + from flask import Blueprint, render_template, request, redirect, url_for, flash from flask_login import login_required -from werkzeug.utils import secure_filename from config import Config xml_bp = Blueprint("xml", __name__) @@ -17,12 +18,26 @@ def allowed_file(filename: str) -> bool: return "." in filename and filename.rsplit(".", 1)[1].lower() in Config.ALLOWED_EXTENSIONS +def sanitize_preserve_unicode(filename: str) -> str: + """ + 디렉터리 탐색/제어 문자를 차단하면서, 한글/유니코드 파일명은 그대로 보존합니다. + - 경로 요소 제거 (Path(...).name) + - 유니코드 정규화(NFC)로 OS간 차이 최소화 + - 널문자/슬래시/역슬래시 차단 + """ + name = Path(filename).name + name = unicodedata.normalize("NFC", name) + if not name or any(ch in name for ch in ["\x00", "/", "\\"]): + raise ValueError("잘못된 파일명입니다.") + return name + + @xml_bp.route("/xml_management") @login_required def xml_management(): xml_dir = Path(Config.XML_FOLDER) try: - files = [f.name for f in xml_dir.iterdir() if f.is_file()] + files = sorted([f.name for f in xml_dir.iterdir() if f.is_file()]) except FileNotFoundError: files = [] flash("XML 폴더가 존재하지 않습니다.", "danger") @@ -37,58 +52,83 @@ def upload_xml(): flash("업로드할 파일을 선택하세요.", "warning") return redirect(url_for("xml.xml_management")) - if allowed_file(file.filename): - filename = secure_filename(file.filename) - save_path = Path(Config.XML_FOLDER) / filename - try: - save_path.parent.mkdir(parents=True, exist_ok=True) - file.save(str(save_path)) - # 텍스트 파일이므로 0644 권장 - try: - save_path.chmod(0o644) - except Exception: - pass # Windows 등에서 무시 - logging.info(f"XML 업로드됨: {filename}") - flash("파일이 성공적으로 업로드되었습니다.", "success") - except Exception as e: - logging.error(f"파일 업로드 오류: {e}") - flash("파일 저장 중 오류가 발생했습니다.", "danger") - else: + if not allowed_file(file.filename): flash("XML 확장자만 업로드할 수 있습니다.", "warning") + return redirect(url_for("xml.xml_management")) + + try: + filename = sanitize_preserve_unicode(file.filename) # 한글/유니코드 보존 + except ValueError: + flash("파일명이 올바르지 않습니다.", "danger") + return redirect(url_for("xml.xml_management")) + + save_path = Path(Config.XML_FOLDER) / filename + try: + save_path.parent.mkdir(parents=True, exist_ok=True) + file.save(str(save_path)) + # 텍스트 파일 권장 권한 (Windows에서는 무시될 수 있음) + try: + save_path.chmod(0o644) + except Exception: + pass + logging.info(f"XML 업로드됨: {filename}") + flash("파일이 성공적으로 업로드되었습니다.", "success") + except Exception as e: + logging.error(f"파일 업로드 오류: {e}") + flash("파일 저장 중 오류가 발생했습니다.", "danger") return redirect(url_for("xml.xml_management")) -@xml_bp.route("/delete_xml/", methods=["POST"]) +@xml_bp.route("/delete_xml/", methods=["POST"]) @login_required def delete_xml(filename: str): - path = Path(Config.XML_FOLDER) / secure_filename(filename) - if path.exists(): - try: - path.unlink() - flash(f"{filename} 파일이 삭제되었습니다.", "success") - logging.info(f"XML 삭제됨: {filename}") - except Exception as e: - logging.error(f"XML 삭제 오류: {e}") - flash("파일 삭제 중 오류 발생", "danger") - else: + try: + safe_name = sanitize_preserve_unicode(filename) + except ValueError: + flash("잘못된 파일명입니다.", "danger") + return redirect(url_for("xml.xml_management")) + + path = Path(Config.XML_FOLDER) / safe_name + if not path.exists(): flash("해당 파일이 존재하지 않습니다.", "warning") + return redirect(url_for("xml.xml_management")) + + try: + path.unlink() + flash(f"{safe_name} 파일이 삭제되었습니다.", "success") + logging.info(f"XML 삭제됨: {safe_name}") + except Exception as e: + logging.error(f"XML 삭제 오류: {e}") + flash("파일 삭제 중 오류 발생", "danger") + return redirect(url_for("xml.xml_management")) -@xml_bp.route("/edit_xml/", methods=["GET", "POST"]) +@xml_bp.route("/edit_xml/", methods=["GET", "POST"]) @login_required def edit_xml(filename: str): - path = Path(Config.XML_FOLDER) / secure_filename(filename) + try: + safe_name = sanitize_preserve_unicode(filename) + except ValueError: + flash("잘못된 파일명입니다.", "danger") + return redirect(url_for("xml.xml_management")) + + path = Path(Config.XML_FOLDER) / safe_name if not path.exists(): flash("파일을 찾을 수 없습니다.", "danger") return redirect(url_for("xml.xml_management")) if request.method == "POST": - new_content = request.form.get("content", "") + raw = request.form.get("content", "") + + # 1) 개행 통일: CRLF/CR → LF + normalized = raw.replace("\r\n", "\n").replace("\r", "\n") + try: - path.write_text(new_content, encoding="utf-8") - logging.info(f"XML 수정됨: {filename}") + # 2) 항상 LF로 저장 (Windows에서도 강제) + path.write_text(normalized, encoding="utf-8", newline="\n") + logging.info(f"XML 수정됨: {safe_name}") flash("파일이 성공적으로 수정되었습니다.", "success") return redirect(url_for("xml.xml_management")) except Exception as e: @@ -96,10 +136,11 @@ def edit_xml(filename: str): flash("파일 저장 중 오류가 발생했습니다.", "danger") try: - content = path.read_text(encoding="utf-8") + # 보기/편집 일관성을 위해 읽을 때도 LF로 맞춰서 textarea에 넣음 + content = path.read_text(encoding="utf-8").replace("\r\n", "\n").replace("\r", "\n") except Exception as e: logging.error(f"XML 열기 실패: {e}") flash("파일 열기 중 오류가 발생했습니다.", "danger") content = "" - return render_template("edit_xml.html", filename=filename, content=content) \ No newline at end of file + return render_template("edit_xml.html", filename=safe_name, content=content) \ No newline at end of file diff --git a/data/logs/2025-10-05.log b/data/logs/2025-10-05.log new file mode 100644 index 0000000..029f965 --- /dev/null +++ b/data/logs/2025-10-05.log @@ -0,0 +1,14 @@ +2025-10-05 16:53:13,743 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-05 16:53:13,777 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-05 16:53:13,777 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-05 16:53:13,899 [INFO] werkzeug: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on all addresses (0.0.0.0) + * Running on http://127.0.0.1:5000 + * Running on http://58.234.69.208:5000 +2025-10-05 16:53:13,899 [INFO] werkzeug: Press CTRL+C to quit +2025-10-05 16:53:13,900 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-05 16:53:14,797 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-05 16:53:14,818 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-05 16:53:14,818 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-05 16:53:14,839 [WARNING] werkzeug: * Debugger is active! +2025-10-05 16:53:14,841 [INFO] werkzeug: * Debugger PIN: 141-667-586 diff --git a/data/logs/app.log b/data/logs/app.log index 029f965..2d0313a 100644 --- a/data/logs/app.log +++ b/data/logs/app.log @@ -1,14 +1,209 @@ -2025-10-05 16:53:13,743 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log -2025-10-05 16:53:13,777 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db -2025-10-05 16:53:13,777 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db -2025-10-05 16:53:13,899 [INFO] werkzeug: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. +2025-10-13 20:46:24,878 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 20:46:24,903 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:24,903 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:25,012 [INFO] werkzeug: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://58.234.69.208:5000 -2025-10-05 16:53:13,899 [INFO] werkzeug: Press CTRL+C to quit -2025-10-05 16:53:13,900 [INFO] werkzeug: * Restarting with watchdog (windowsapi) -2025-10-05 16:53:14,797 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log -2025-10-05 16:53:14,818 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db -2025-10-05 16:53:14,818 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db -2025-10-05 16:53:14,839 [WARNING] werkzeug: * Debugger is active! -2025-10-05 16:53:14,841 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 20:46:25,013 [INFO] werkzeug: Press CTRL+C to quit +2025-10-13 20:46:25,016 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 20:46:25,793 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 20:46:25,812 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:25,812 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:25,832 [WARNING] werkzeug: * Debugger is active! +2025-10-13 20:46:25,834 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 20:46:33,645 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:33] "GET / HTTP/1.1" 302 - +2025-10-13 20:46:33,681 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:33] "GET /login?next=/ HTTP/1.1" 200 - +2025-10-13 20:46:33,726 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:33] "GET /static/style.css HTTP/1.1" 200 - +2025-10-13 20:46:33,761 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:33] "GET /static/favicon.ico HTTP/1.1" 200 - +2025-10-13 20:46:43,092 [INFO] app: LOGIN: form ok email=ganghee@zespro.co.kr +2025-10-13 20:46:43,092 [INFO] app: LOGIN: form ok email=ganghee@zespro.co.kr +2025-10-13 20:46:43,164 [INFO] app: LOGIN: found id=1 active=True pass_ok=True +2025-10-13 20:46:43,164 [INFO] app: LOGIN: found id=1 active=True pass_ok=True +2025-10-13 20:46:43,165 [INFO] app: LOGIN: SUCCESS → redirect +2025-10-13 20:46:43,165 [INFO] app: LOGIN: SUCCESS → redirect +2025-10-13 20:46:43,166 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:43] "POST /login HTTP/1.1" 302 - +2025-10-13 20:46:43,208 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:43] "GET /index HTTP/1.1" 200 - +2025-10-13 20:46:43,228 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:43] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 20:46:43,239 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:43] "GET /static/script.js HTTP/1.1" 200 - +2025-10-13 20:46:43,700 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\auth.py', reloading +2025-10-13 20:46:43,960 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 20:46:44,783 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 20:46:44,806 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:44,806 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 20:46:44,830 [WARNING] werkzeug: * Debugger is active! +2025-10-13 20:46:44,831 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 20:46:50,381 [INFO] root: file_view: folder=idrac_info date= filename=1PYCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\1PYCZC4.txt +2025-10-13 20:46:50,381 [INFO] root: file_view: folder=idrac_info date= filename=1PYCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\1PYCZC4.txt +2025-10-13 20:46:50,390 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:50] "GET /view_file?folder=idrac_info&filename=1PYCZC4.txt HTTP/1.1" 200 - +2025-10-13 20:46:50,391 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:50] "GET /view_file?folder=idrac_info&filename=1PYCZC4.txt HTTP/1.1" 200 - +2025-10-13 20:46:52,148 [INFO] root: file_view: folder=idrac_info date= filename=FWZCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\FWZCZC4.txt +2025-10-13 20:46:52,148 [INFO] root: file_view: folder=idrac_info date= filename=FWZCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\FWZCZC4.txt +2025-10-13 20:46:52,156 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:52] "GET /view_file?folder=idrac_info&filename=FWZCZC4.txt HTTP/1.1" 200 - +2025-10-13 20:46:52,156 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:46:52] "GET /view_file?folder=idrac_info&filename=FWZCZC4.txt HTTP/1.1" 200 - +2025-10-13 20:59:08,054 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:59:08] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 20:59:08,094 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:59:08] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 20:59:10,603 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:59:10] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 20:59:10,610 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:59:10] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 20:59:10,628 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 20:59:10] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:01:45,024 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\app.py', reloading +2025-10-13 21:01:45,025 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\auth.py', reloading +2025-10-13 21:01:45,025 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\utilities.py', reloading +2025-10-13 21:01:46,120 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 21:01:47,037 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 21:01:47,057 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:01:47,057 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:01:47,079 [WARNING] werkzeug: * Debugger is active! +2025-10-13 21:01:47,080 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 21:03:00,929 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:00] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:03:00,969 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:00] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:03:01,001 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /static/favicon.ico HTTP/1.1" 304 - +2025-10-13 21:03:01,726 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:03:01,741 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:03:01,762 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /static/favicon.ico HTTP/1.1" 304 - +2025-10-13 21:03:01,885 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:03:01,900 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:03:01,920 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:03:01] "GET /static/favicon.ico HTTP/1.1" 304 - +2025-10-13 21:27:00,213 [ERROR] werkzeug: 176.32.195.85 - - [13/Oct/2025 21:27:00] code 400, message Bad request version ("¯nãY»bhlÿ(=':©\x82ÙoÈ¢×\x93\x98´ï\x80å¹\x90\x00(À") +2025-10-13 21:27:00,214 [INFO] werkzeug: 176.32.195.85 - - [13/Oct/2025 21:27:00] "\x16\x03\x02\x01o\x01\x00\x01k\x03\x02RHÅ\x1a#÷:Nßâ´\x82/ÿ\x09T\x9f§Äy°hÆ\x13\x8c¤\x1c="á\x1a\x98 \x84´,\x85¯nãY»bhlÿ(=':©\x82ÙoÈ¢×\x93\x98´ï\x80å¹\x90\x00(À" 400 - +2025-10-13 21:53:20,275 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:20] "GET /xml_management HTTP/1.1" 302 - +2025-10-13 21:53:20,284 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:20] "GET /login?next=/xml_management HTTP/1.1" 200 - +2025-10-13 21:53:20,304 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:20] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:53:20,328 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:20] "GET /static/favicon.ico HTTP/1.1" 304 - +2025-10-13 21:53:32,213 [INFO] app: LOGIN: form ok email=ganghee@zespro.co.kr +2025-10-13 21:53:32,213 [INFO] app: LOGIN: form ok email=ganghee@zespro.co.kr +2025-10-13 21:53:32,262 [INFO] app: LOGIN: found id=1 active=True pass_ok=True +2025-10-13 21:53:32,262 [INFO] app: LOGIN: found id=1 active=True pass_ok=True +2025-10-13 21:53:32,263 [INFO] app: LOGIN: SUCCESS → redirect +2025-10-13 21:53:32,263 [INFO] app: LOGIN: SUCCESS → redirect +2025-10-13 21:53:32,264 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:32] "POST /login HTTP/1.1" 302 - +2025-10-13 21:53:32,284 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:32] "GET /index HTTP/1.1" 200 - +2025-10-13 21:53:32,305 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:32] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:53:32,306 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:32] "GET /static/script.js HTTP/1.1" 304 - +2025-10-13 21:53:32,776 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\auth.py', reloading +2025-10-13 21:53:33,286 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 21:53:34,214 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 21:53:34,238 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:53:34,238 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:53:34,264 [WARNING] werkzeug: * Debugger is active! +2025-10-13 21:53:34,266 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 21:53:34,514 [INFO] root: file_view: folder=idrac_info date= filename=1PYCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\1PYCZC4.txt +2025-10-13 21:53:34,514 [INFO] root: file_view: folder=idrac_info date= filename=1PYCZC4.txt | base=D:\Code\iDRAC_Info\idrac_info\data\idrac_info | target=D:\Code\iDRAC_Info\idrac_info\data\idrac_info\1PYCZC4.txt +2025-10-13 21:53:34,515 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:34] "GET /view_file?folder=idrac_info&filename=1PYCZC4.txt HTTP/1.1" 200 - +2025-10-13 21:53:34,517 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:53:34] "GET /view_file?folder=idrac_info&filename=1PYCZC4.txt HTTP/1.1" 200 - +2025-10-13 21:55:55,966 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:55] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:55:56,007 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:56] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:55:56,226 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:56] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:55:56,242 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:56] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:55:56,916 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:56] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 21:55:56,931 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:55:56] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:57:26,121 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\utilities.py', reloading +2025-10-13 21:57:26,773 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 21:57:27,733 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 21:57:27,754 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:27,754 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:27,776 [WARNING] werkzeug: * Debugger is active! +2025-10-13 21:57:27,778 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 21:57:38,241 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\file_view.py', reloading +2025-10-13 21:57:38,936 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 21:57:39,993 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 21:57:40,013 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:40,013 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:40,035 [WARNING] werkzeug: * Debugger is active! +2025-10-13 21:57:40,036 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 21:57:46,976 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\xml.py', reloading +2025-10-13 21:57:47,142 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 21:57:48,215 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 21:57:48,239 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:48,239 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 21:57:48,263 [WARNING] werkzeug: * Debugger is active! +2025-10-13 21:57:48,265 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 21:58:54,150 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:58:54] "GET /index HTTP/1.1" 200 - +2025-10-13 21:58:54,207 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:58:54] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 21:58:54,211 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 21:58:54] "GET /static/script.js HTTP/1.1" 304 - +2025-10-13 22:01:38,304 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\xml.py', reloading +2025-10-13 22:01:38,693 [INFO] werkzeug: * Restarting with watchdog (windowsapi) +2025-10-13 22:01:39,585 [INFO] root: Logger initialized | level=INFO | file=D:\Code\iDRAC_Info\idrac_info\data\logs\app.log +2025-10-13 22:01:39,606 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 22:01:39,606 [INFO] app: DB URI = sqlite:///D:/Code/iDRAC_Info/idrac_info/backend/instance/site.db +2025-10-13 22:01:39,629 [WARNING] werkzeug: * Debugger is active! +2025-10-13 22:01:39,631 [INFO] werkzeug: * Debugger PIN: 141-667-586 +2025-10-13 22:01:41,777 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:41] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:01:41,820 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:41] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:01:43,249 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:43] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:01:43,266 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:43] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:01:52,082 [INFO] root: XML 수정됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:01:52,083 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:52] "POST /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:01:52,089 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:52] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:01:52,108 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:52] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:01:54,303 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:54] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:01:54,320 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:01:54] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:07,198 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:07] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:02:07,218 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:07] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:13,613 [INFO] root: XML 삭제됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:02:13,614 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:13] "POST /delete_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:02:13,620 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:13] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:02:13,655 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:13] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:34,242 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:34] "POST /upload_xml HTTP/1.1" 302 - +2025-10-13 22:02:34,248 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:34] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:02:34,265 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:34] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:40,425 [INFO] root: XML 업로드됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:02:40,426 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:40] "POST /upload_xml HTTP/1.1" 302 - +2025-10-13 22:02:40,431 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:40] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:02:40,451 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:40] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:49,269 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:49] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:02:49,286 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:49] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:58,452 [INFO] root: XML 수정됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:02:58,453 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:58] "POST /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:02:58,460 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:58] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:02:58,481 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:58] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:02:59,976 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:59] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:02:59,994 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:02:59] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:03,710 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:03] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:03,738 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:03] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:12,093 [INFO] root: XML 삭제됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:12,094 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:12] "POST /delete_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:03:12,100 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:12] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:12,117 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:12] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:16,786 [INFO] root: XML 업로드됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:16,787 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:16] "POST /upload_xml HTTP/1.1" 302 - +2025-10-13 22:03:16,792 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:16] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:16,810 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:16] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:18,824 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:18] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:03:18,842 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:18] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:20,517 [INFO] root: XML 수정됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:20,517 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:20] "POST /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:03:20,523 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:20] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:20,541 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:20] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:21,471 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:21] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:03:21,488 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:21] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:22,862 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:22] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:22,882 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:22] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:24,843 [INFO] root: XML 삭제됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:24,843 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:24] "POST /delete_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:03:24,850 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:24] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:24,867 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:24] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:29,647 [INFO] root: XML 업로드됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:29,648 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:29] "POST /upload_xml HTTP/1.1" 302 - +2025-10-13 22:03:29,653 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:29] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:29,671 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:29] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:32,324 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:32] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:03:32,342 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:32] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:41,018 [INFO] root: XML 수정됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:03:41,019 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:41] "POST /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:03:41,024 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:41] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:03:41,043 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:41] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:03:42,366 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:42] "GET /edit_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 200 - +2025-10-13 22:03:42,383 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:03:42] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:04:08,315 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:08] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:04:08,335 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:08] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:04:10,894 [INFO] root: XML 삭제됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:04:10,894 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:10] "POST /delete_xml/PO-20250826-0158%20_가산3_XE9680_384EA.xml HTTP/1.1" 302 - +2025-10-13 22:04:10,900 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:10] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:04:10,918 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:10] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:04:13,763 [INFO] root: XML 업로드됨: PO-20250826-0158 _가산3_XE9680_384EA.xml +2025-10-13 22:04:13,764 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:13] "POST /upload_xml HTTP/1.1" 302 - +2025-10-13 22:04:13,769 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:13] "GET /xml_management HTTP/1.1" 200 - +2025-10-13 22:04:13,787 [INFO] werkzeug: 127.0.0.1 - - [13/Oct/2025 22:04:13] "GET /static/style.css HTTP/1.1" 304 - +2025-10-13 22:06:39,759 [INFO] werkzeug: * Detected change in 'D:\\Code\\iDRAC_Info\\idrac_info\\backend\\routes\\xml.py', reloading +2025-10-13 22:06:40,155 [INFO] werkzeug: * Restarting with watchdog (windowsapi)