From 136bb4d0901a66d1b29cf799c86703ccc5b163f0 Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 22:55:07 +0800 Subject: [PATCH 1/9] feat: implemented file-upload --- .env | 10 +++++++ .gitignore | 1 + app.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++ config.py | 14 ++++++++++ extensions.py | 4 +++ requirements.txt | Bin 0 -> 522 bytes 6 files changed, 96 insertions(+) create mode 100644 .env create mode 100644 .gitignore create mode 100644 app.py create mode 100644 config.py create mode 100644 extensions.py create mode 100644 requirements.txt diff --git a/.env b/.env new file mode 100644 index 0000000..4985661 --- /dev/null +++ b/.env @@ -0,0 +1,10 @@ +# Flask Environment +FLASK_ENV=development +UPLOAD_FOLDER=uploads + +# Database Configuration +DB_USER=root +DB_PASSWORD=betache2025 +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=flask_uploads_db diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c2ad09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/app.py b/app.py new file mode 100644 index 0000000..5f341c9 --- /dev/null +++ b/app.py @@ -0,0 +1,67 @@ +import os +import logging +from flask import Flask +from config import Config +from extensions import db # import db from extensions +from sqlalchemy import create_engine +from sqlalchemy.exc import OperationalError + +# --------------------------- +# Initialize Flask app +# --------------------------- +app = Flask(__name__) +app.config.from_object(Config) + +# --------------------------- +# Ensure database exists +# --------------------------- +db_uri = app.config['SQLALCHEMY_DATABASE_URI'] +# Extract database name from URI +db_name = db_uri.rsplit('/', 1)[-1] +engine_uri_without_db = db_uri.rsplit('/', 1)[0] + +try: + engine = create_engine(db_uri) + conn = engine.connect() + conn.close() +except OperationalError: + # Database doesn't exist, create it + engine = create_engine(engine_uri_without_db) + conn = engine.connect() + conn.execute(f"CREATE DATABASE {db_name}") + conn.close() + print(f"Database '{db_name}' created successfully.") + +# --------------------------- +# Initialize database +# --------------------------- +db.init_app(app) # initialize db with app + +# --------------------------- +# Configure logging +# --------------------------- +os.makedirs(app.config['LOG_FOLDER'], exist_ok=True) +logging.basicConfig( + filename=f"{app.config['LOG_FOLDER']}/app.log", + level=logging.INFO, + format='%(asctime)s [%(levelname)s] %(message)s' +) + +# --------------------------- +# Register blueprints +# --------------------------- +# Import blueprints AFTER app and db are initialized +from controllers.file_controller import file_bp +app.register_blueprint(file_bp) + +# --------------------------- +# Create database tables if they don't exist +# --------------------------- +with app.app_context(): + db.create_all() + +# --------------------------- +# Run the app +# --------------------------- +if __name__ == '__main__': + app.run(debug=True) diff --git a/config.py b/config.py new file mode 100644 index 0000000..815e842 --- /dev/null +++ b/config.py @@ -0,0 +1,14 @@ +import os +from dotenv import load_dotenv + +load_dotenv() # Load .env variables + +class Config: + SQLALCHEMY_DATABASE_URI = ( + f"mysql+pymysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@" + f"{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}" + ) + SQLALCHEMY_TRACK_MODIFICATIONS = False + UPLOAD_FOLDER = os.getenv('UPLOAD_FOLDER', 'uploads') + LOG_FOLDER = 'logs' + DEBUG = True diff --git a/extensions.py b/extensions.py new file mode 100644 index 0000000..cebd4b6 --- /dev/null +++ b/extensions.py @@ -0,0 +1,4 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..a2fbb496ea1102651203c1551504362dea0cffe3 GIT binary patch literal 522 zcmZ{hO-sXI5QOI}_){uPtfB`GUOb2e#e+wQF{ZUP3HcE9$E(l0Zxcn3u!QW)&dzMU zJ|Fa=wJL2?sMQ%yq63{$bM0$SdBAgUV<+?ve_=If&0MA}WyTzIK^=$b3-Cu(L Date: Sun, 19 Oct 2025 22:59:42 +0800 Subject: [PATCH 2/9] Delete .env --- .env | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 4985661..0000000 --- a/.env +++ /dev/null @@ -1,10 +0,0 @@ -# Flask Environment -FLASK_ENV=development -UPLOAD_FOLDER=uploads - -# Database Configuration -DB_USER=root -DB_PASSWORD=betache2025 -DB_HOST=localhost -DB_PORT=3306 -DB_NAME=flask_uploads_db From 3a1ed9cefa5855a464bce735322d0340f2ec1fba Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 22:59:59 +0800 Subject: [PATCH 3/9] Delete .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0c2ad09..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.env From 61fced6300092442fac6a31b8ca62dbbee2c9660 Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:00:20 +0800 Subject: [PATCH 4/9] Delete app.py --- app.py | 67 ---------------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 app.py diff --git a/app.py b/app.py deleted file mode 100644 index 5f341c9..0000000 --- a/app.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import logging -from flask import Flask -from config import Config -from extensions import db # import db from extensions -from sqlalchemy import create_engine -from sqlalchemy.exc import OperationalError - -# --------------------------- -# Initialize Flask app -# --------------------------- -app = Flask(__name__) -app.config.from_object(Config) - -# --------------------------- -# Ensure database exists -# --------------------------- -db_uri = app.config['SQLALCHEMY_DATABASE_URI'] -# Extract database name from URI -db_name = db_uri.rsplit('/', 1)[-1] -engine_uri_without_db = db_uri.rsplit('/', 1)[0] - -try: - engine = create_engine(db_uri) - conn = engine.connect() - conn.close() -except OperationalError: - # Database doesn't exist, create it - engine = create_engine(engine_uri_without_db) - conn = engine.connect() - conn.execute(f"CREATE DATABASE {db_name}") - conn.close() - print(f"Database '{db_name}' created successfully.") - -# --------------------------- -# Initialize database -# --------------------------- -db.init_app(app) # initialize db with app - -# --------------------------- -# Configure logging -# --------------------------- -os.makedirs(app.config['LOG_FOLDER'], exist_ok=True) -logging.basicConfig( - filename=f"{app.config['LOG_FOLDER']}/app.log", - level=logging.INFO, - format='%(asctime)s [%(levelname)s] %(message)s' -) - -# --------------------------- -# Register blueprints -# --------------------------- -# Import blueprints AFTER app and db are initialized -from controllers.file_controller import file_bp -app.register_blueprint(file_bp) - -# --------------------------- -# Create database tables if they don't exist -# --------------------------- -with app.app_context(): - db.create_all() - -# --------------------------- -# Run the app -# --------------------------- -if __name__ == '__main__': - app.run(debug=True) From 95dcf3877bebf11e43dbff8269a0b932d9a49748 Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:00:33 +0800 Subject: [PATCH 5/9] Delete config.py --- config.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 config.py diff --git a/config.py b/config.py deleted file mode 100644 index 815e842..0000000 --- a/config.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -from dotenv import load_dotenv - -load_dotenv() # Load .env variables - -class Config: - SQLALCHEMY_DATABASE_URI = ( - f"mysql+pymysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@" - f"{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}" - ) - SQLALCHEMY_TRACK_MODIFICATIONS = False - UPLOAD_FOLDER = os.getenv('UPLOAD_FOLDER', 'uploads') - LOG_FOLDER = 'logs' - DEBUG = True From 695d24be87a3395689b6ceceb72887b762f664b0 Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:00:46 +0800 Subject: [PATCH 6/9] Delete extensions.py --- extensions.py | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 extensions.py diff --git a/extensions.py b/extensions.py deleted file mode 100644 index cebd4b6..0000000 --- a/extensions.py +++ /dev/null @@ -1,4 +0,0 @@ -from flask_sqlalchemy import SQLAlchemy - -db = SQLAlchemy() - From 47a018e08d4fc53714ae187bd43d7197b0138d03 Mon Sep 17 00:00:00 2001 From: b1nsz <107747489+b1nsz@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:01:07 +0800 Subject: [PATCH 7/9] Delete requirements.txt --- requirements.txt | Bin 522 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a2fbb496ea1102651203c1551504362dea0cffe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522 zcmZ{hO-sXI5QOI}_){uPtfB`GUOb2e#e+wQF{ZUP3HcE9$E(l0Zxcn3u!QW)&dzMU zJ|Fa=wJL2?sMQ%yq63{$bM0$SdBAgUV<+?ve_=If&0MA}WyTzIK^=$b3-Cu(L Date: Sun, 19 Oct 2025 23:31:04 +0800 Subject: [PATCH 8/9] feat:implented file-upload --- .gitignore | 1 + .vs/VSWorkspaceState.json | 12 ++ ...27285a50-d78a-45bc-8587-71ceed15b967.vsidx | Bin 0 -> 11673 bytes ...38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx | Bin 0 -> 2259 bytes ...7716003e-af54-4dc2-8aea-99215f903983.vsidx | Bin 0 -> 6570 bytes ...917f158e-4d76-47b1-8689-f1817d69a700.vsidx | Bin 0 -> 9695 bytes ...be2fea4f-3e12-4e63-931a-b796639777c8.vsidx | Bin 0 -> 6598 bytes .vs/flask_file_upload_mvc/v17/.wsuo | Bin 0 -> 35328 bytes .../v17/DocumentLayout.backup.json | 136 ++++++++++++++++++ .../v17/DocumentLayout.json | 136 ++++++++++++++++++ .vs/slnx.sqlite | Bin 0 -> 90112 bytes __pycache__/app.cpython-314.pyc | Bin 0 -> 1318 bytes __pycache__/config.cpython-314.pyc | Bin 0 -> 1033 bytes __pycache__/extensions.cpython-314.pyc | Bin 0 -> 241 bytes app.py | 67 +++++++++ config.py | 14 ++ .../file_controller.cpython-314.pyc | Bin 0 -> 4085 bytes controllers/file_controller.py | 81 +++++++++++ extensions.py | 4 + logs/app.log | 17 +++ .../__pycache__/uploaded_file.cpython-314.pyc | Bin 0 -> 832 bytes models/uploaded_file.py | 7 + requirements.txt | Bin 0 -> 522 bytes .../__pycache__/file_service.cpython-314.pyc | Bin 0 -> 4000 bytes services/file_service.py | 78 ++++++++++ 25 files changed, 553 insertions(+) create mode 100644 .gitignore create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx create mode 100644 .vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx create mode 100644 .vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx create mode 100644 .vs/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx create mode 100644 .vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx create mode 100644 .vs/flask_file_upload_mvc/v17/.wsuo create mode 100644 .vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json create mode 100644 .vs/flask_file_upload_mvc/v17/DocumentLayout.json create mode 100644 .vs/slnx.sqlite create mode 100644 __pycache__/app.cpython-314.pyc create mode 100644 __pycache__/config.cpython-314.pyc create mode 100644 __pycache__/extensions.cpython-314.pyc create mode 100644 app.py create mode 100644 config.py create mode 100644 controllers/__pycache__/file_controller.cpython-314.pyc create mode 100644 controllers/file_controller.py create mode 100644 extensions.py create mode 100644 logs/app.log create mode 100644 models/__pycache__/uploaded_file.cpython-314.pyc create mode 100644 models/uploaded_file.py create mode 100644 requirements.txt create mode 100644 services/__pycache__/file_service.cpython-314.pyc create mode 100644 services/file_service.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6daf1ee --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,12 @@ +{ + "ExpandedNodes": [ + "", + "\\controllers", + "\\controllers\\__pycache__", + "\\models", + "\\services", + "\\uploads" + ], + "SelectedNode": "\\app.py", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx b/.vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..673080df85fb8225a71a8e488c718bbd770907fb GIT binary patch literal 11673 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 literal 0 HcmV?d00001 diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx b/.vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..b3a5cc6239ce7035b905700e14b0133f0d0fe8af GIT binary patch literal 2259 zcmc&#OK;Oa5Z;6qC{Rjxh%>ix!1AsiS#z@j1w^B^0S*i+h7RwrQI}%C;v=T16uD|K^U+5L=tA#6&1{oGe~KV{!` z+Qfc+_wzShKg&)-_2Svyv*?ZDa+Lj2H3Go?5`z1o01M4e za2-C|WF62i*mJ@j>@w#zoa?t|{JEp6?xXJFrkULo|wwoR?EjN`CvOOIR!?6H@+ o-eWtu7tYevK5#VJcG)_+ujks)Ye9uPVN58iNDjzr!n;KDZ>q?PqW}N^ literal 0 HcmV?d00001 diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx b/.vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..bffecb82c4410af9bc1fea1220d4b12cd3044a56 GIT binary patch literal 6570 zcmYkA2Vm6Y8OA>_B2K`KGsfs88ZLlwMS@&%cgaDxJ8pzT5>5<3BZ0&OXf=(+4z;aq zwR_KK?WW6Gt8MMJ!wzd(s@4v>_pV*~JkR$;8vghEzW@7u-}}DbOpdN}_mYJn+_*I8 zXD}l4gI(=|)v1xmsln9N9iux3r^a_r4v!2@j!cYC4Q?CTGPS+7ZFFp;wtHf1e9P9_ zjy=PJ!{a-5O^%O^v6Jc!7?Km$ZocQfhv%mroi|z+gB&F64WT}S#t@Ljq0)IFOwARZ z3;_)~^@;|!gm9$Fx2f?Ol^2JQ3t={d%^~cU1+TYL7r zs8d|Tx-Nt}^q^%NJN%#)K~X@L%R)FHZZ0`*sI~73u$q5R0eOw8k4MM-5C6XwT?-;K6Lf@-9tm> zZSWvURCquR7zmC7jJ3IlsKr3=pfAd^bBeeN?>#)|2X_6yF^8!SB8a?~M#uMw!Gt36_OtaBE%RJjmm`!H0d5(Fm*HhWBLLfO}v>&#vgca`e# z>qjh@MRS9Rov-?`Suv|-pSjWOHwR4Ip6b8J95jc_%_a_t+FfpLF|RO(&8_B$xy`)N zyviIkuQs=vW9ANXr#Ws;nAez-=9GzBM|tix_n6NzpKV@iUT035&oO7r>&@qyd(9in z=b6tpUtqq_ywSYLyxDw_`C{`W<}Kz+&6k-kH*Ym>Ghbo8(tMTqYV$SbYt7f0uQ%Ud zzR`S>`DXJi=3C9TnQu4WVZPIxHE%cXFyCd~X};ThkNIBnedhbk511b`_n99uKWu)) z{HXac^Dgt_=H2Ee%zMmFn)jObnV&L0ZGOhQ-~6okIrH=87tAl3UoyXJK45;u{Hpmi z^Xuk=<~Pi5n%^?NZ9Zgv$9&lQuK7Ll`{sW02j(N@qvm7g56#ETADKTke`5aBe8T*h z`E&CZ<}b}(nZGuFWB%6so%wt759S}uKbe0v|6=~t{G0iA^B?9v%_q%&ng2HbWB%9t zpZS!@%LPxEXU;bdGV9EP%?0Km=0fvO^Dy&p^9b`u^C)wXx!7D{9&H|D9%~+F9&est zo@g#LPclz7Pcct5Pcu(9>&-LF2J=j_(LBpM+f0~EX0v&Yd9K-FE;Ey6tGV1P?<>nUi3Uk=pYL1xO%qz{S%u(}dbGtca z?l5F(B1$!^ z#5b(v(iNdi8MVnmZ42#c&z||v5i0Q75jG*W)%di8HL6V^s~*e&=Y^V))}WlRl;$dh zc$}wlSSMv|MYR?6t>7&c`e5k{y~wH)trJp?xeIoFiqbN)2VOZBd1w_`F?NfzT{;78 zM)qlpJ}c$AaVF9lWm+RhD+^|v#=neOW)Poc`s7@t5oIH^jFG4DRWXaY1UyrRpj=gI zvy`=5F|G#7T#bz8KF$gwu|0F4vJJg5YDQXy=3%39hKk69$}(4$nbAW@5lgBqY352{ z0QRyxmz7}|Z?v#)8S9ooiG3@`m&%Boe=4I?yR%8!B5jv;NNZ@vn}G2$QqBR_iZekwqs2KYVCOZVT*7)$D^U99K4846 z%3K4U!#uL*O!8Lil9r&nON#KzTZVJP5z)g5N64HoOdUcYs0Zq zIR>6i-Ua;4$`inyK?~QMN=pegDtmF}7?bTe0{;HX>5i;vCAy?(?Wf-VyW`5b;~I2| zTBI{j{x;^y#rq|#+006#rKoZh^E!i*%TX1d85@6(@viKL@_bPXP>zUaD+T5LJ#cR} uqs$uq1+X5e?&1 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 G>G>~p$Gfrs literal 0 HcmV?d00001 diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx b/.vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..70eb51f1ef4fa7d09f7c1183118670d14b0b43e7 GIT binary patch literal 6598 zcmX|^31F1f6@^~_0dWBY_XUj0Bp64~xJ4pNGBe4LWG2i40fG|@0V4^CL{OWiO}bHQ zt=)HP(QevWyJ%|{3*EGfZEZ_8YZqEA-R-7!x96O9(lB$r_uv1%`|i7M329BYEu0&| zohJwVtcwUmu(heTGB&VltT(lFcyMR$*vRf({R6$b21ZB5dbbU28QW3aHaIj;-90)q zvSn*^cu#*Xy!Q=4Ex_d_IiJFmFG5kznQ3wk{m=QvaKC!)g`f*+e zOG7wK4)BSeXu+$-5DtU@=i5S<9YS9S(H}A417~!^wBU1C4tNXa#d-^egECI(5q-~4 z1O71x9MC{kXh88nz=UGLvPzBpA>5_>ACSYo5S|I)Ifa4+b3p?4g)kMut!g7e3Wgj+&D;rgbtnxo|50}EnetSKpm!&vadOpz@d z&^;Cq!SRSvz~>^hCsjjC84f5QGJ(PkF=2!!<^oUT`A`UZLs+5--YW~@!;Z|K*H}pV zq!3;p%fqrD0-`leFVg{4KBkIn(H9ZsXliKVgE;82N^W?Cq2Y$dJCrIiL^WVssrfF} zKo}h#ObQ?LMGmMEER!K@*EBJgr}Y+b63PS(I3pVL2+gQQZ76bpJ-#|Toe6S4Ko}8! zzvhTnNDszmRcEA!x}i$�Rf15Q1akND>WXh3?S@4HO?aV4t8|aTK)oDIj9vgD!}G z2HX%l<}*2+13Zz*l;WU!UkJy@g37})IwJx;C_Z$xs)5Eq^+E$R#126|NDM>75%GxR z9|_?x^+G$^5fE`|Gz5(3j+st{a7Y1RhudiakqjckKL)SW`eGt`wUjWTZ`_~gvP`)lGBTX^ z=utsG=&PR^==2x9YR@z=gr2cMM2srVF&Tq>k2Eoao;d{VN1Iq0Js)e%H!)?|7n;YJ zi_FF5@#YEUi6)Au{=Ba_-YMp(CTcGG=_XcJ&sYU)DhWZr9j*u2mDi1|_TW9G-r`^^W;Pne%HA2dH@e%kzu`C0QJ^K<5Y^MLtz^9$w| z%`cf>HXk-0F~4Gd)%=?Ib@Ng48|F97Z<&vo-!{Kve%Cx`e$V{A`2+KZ=8w$B%^#aj zm_IRpYW~dpxp~O^h51YKN%JZ5SLR{!*XD1`-!~CcDFZ18#f6V`y&zrm~@Ch~M40EPA%RIuIZO$?0nn#-R%%jYs&11}C z&H3g6bD?>hxyW2>9&esto@kzAo@}0Co@$2{{HD-s|X?B@;vtV|cYt5orGRtPgTxYH~d&~{yMst(dYi>5LGOK2vxy8KN z>^HZX1Lih!yLpW{XkKgXFo(=xbEi3Cj+)n*yUa23dULnA$GpM3(R_R^4l#aa<6Hax zf30ezr6p+v+8WxS>5zeDLk?OBDQG2hL&w2HNaCB&+eBCcdjj9IG!HF@9{f>4FKQNA zuXYRK)FCe4W)X{;gXUqY(W#7`o(0+hKW6(^|($l@Z5HAsQo;-EK#F9oj7zwWR1Jtx87o?~)dw zoJA{gC?Z}0xusRhG+Iq)vwqa9v;yS}m}42r*vy!gj9M9aW{@o{jG0ALY7Ux{h4V^> zs(MuMhU=D*#`g3|W|RXfT8p>Lfx1>2YtMPJew;nWi?eSHtQl81&WxEQ&`x7URK{U0 zRA#|EGgy84bn3Yi8D>ytM&Q~|X(=kxBJyIpLCUd;ickz2&@RcdEKjaQ29;ul745I} z8nH*C_h_wp!UW#NI#gw^Vl-O1rOa&t72saaO2?tx&#Y-Dw1Bawv0XvCh$qgc0m`~j zbJCba8SOS%xX*c3nxH%l)HP7XJj+_`G;|{(#C^v+>Xc2r zv_Z;~%$1~;rBx_L;OS!h3YamqO}ZY+v)!rn-0*g(m8PVv(lnIkn`b)#&ERj)yw;YrqlGI;ZGy6Xc|IaW*OZ*Whn0hY8J|q z)QvB1b5@sHfHG^&zo=D@XDOkP>Y?0$MMQ}=1TDOEsI>EBQ{!#br8e(Qo|2+go;#j) z#^*n>gjrC#p*(>+pGjF;q&%yv64$s(+AWPYdIfFXpxl?O(s;6~XmkH^r!pGn$2Z)& zJnz)lrnQU=OBkJ1OyKlzPxE&he+y8vP~QFQStpHmSX%A8vZQDuSQly)%H72inTB!?QgcwQEtMyMRj1~mtPMw_ z5BsgdTspNs>ZECDReL2ZEkb!Zcn@ZAqp(uUFCpa}Gl4f;r#5Ar(W$QJclqYP-=Lj% zPe1n0NefWs%zHBhNV=P{&z!}h3|Yn4VzEW Kh@S@+ME(y}8eeh% literal 0 HcmV?d00001 diff --git a/.vs/flask_file_upload_mvc/v17/.wsuo b/.vs/flask_file_upload_mvc/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..ecd7d0ee9c8246e9d5ac7a69d6f63970379a4cb3 GIT binary patch literal 35328 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 literal 0 HcmV?d00001 diff --git a/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json b/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..0a475b7 --- /dev/null +++ b/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json @@ -0,0 +1,136 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:models\\uploaded_file.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:app.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\extensions.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:models\\extensions.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:services\\file_service.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:config.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:controllers\\file_controller.py||{8B382828-6202-11D1-8870-0000F87579D2}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 1, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedHeight": 311, + "SelectedChildIndex": 3, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "extensions.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\extensions.py", + "RelativeDocumentMoniker": "models\\extensions.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\extensions.py", + "RelativeToolTip": "models\\extensions.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:54:33.993Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "file_controller.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py", + "RelativeDocumentMoniker": "controllers\\file_controller.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py", + "RelativeToolTip": "controllers\\file_controller.py", + "ViewState": "AgIAAD8AAAAAAAAAAAAuwEoAAAAnAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:29:53.424Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "file_service.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py", + "RelativeDocumentMoniker": "services\\file_service.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py", + "RelativeToolTip": "services\\file_service.py", + "ViewState": "AgIAACQAAAAAAAAAAAAAACkAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:27:19.887Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "uploaded_file.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py", + "RelativeDocumentMoniker": "models\\uploaded_file.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py", + "RelativeToolTip": "models\\uploaded_file.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:25:46.102Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "app.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py", + "RelativeDocumentMoniker": "app.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py", + "RelativeToolTip": "app.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACwAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:21:09.174Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "config.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py", + "RelativeDocumentMoniker": "config.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py", + "RelativeToolTip": "config.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:18:24.643Z", + "EditorCaption": "" + } + ] + }, + { + "DockedHeight": 126, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{34e76e81-ee4a-11d0-ae2e-00a0c90fffc3}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/flask_file_upload_mvc/v17/DocumentLayout.json b/.vs/flask_file_upload_mvc/v17/DocumentLayout.json new file mode 100644 index 0000000..eb6b5d7 --- /dev/null +++ b/.vs/flask_file_upload_mvc/v17/DocumentLayout.json @@ -0,0 +1,136 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:app.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:config.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:controllers\\file_controller.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:models\\uploaded_file.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:services\\file_service.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\extensions.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:extensions.py||{8B382828-6202-11D1-8870-0000F87579D2}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 1, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedHeight": 311, + "SelectedChildIndex": 4, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "extensions.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\extensions.py", + "RelativeDocumentMoniker": "extensions.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\extensions.py", + "RelativeToolTip": "extensions.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:54:33.993Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "file_controller.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py", + "RelativeDocumentMoniker": "controllers\\file_controller.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\controllers\\file_controller.py", + "RelativeToolTip": "controllers\\file_controller.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:29:53.424Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "file_service.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py", + "RelativeDocumentMoniker": "services\\file_service.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\services\\file_service.py", + "RelativeToolTip": "services\\file_service.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAQAAAA6AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:27:19.887Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "uploaded_file.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py", + "RelativeDocumentMoniker": "models\\uploaded_file.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\models\\uploaded_file.py", + "RelativeToolTip": "models\\uploaded_file.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:25:46.102Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "app.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py", + "RelativeDocumentMoniker": "app.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py", + "RelativeToolTip": "app.py", + "ViewState": "AgIAADAAAAAAAAAAAAAAAEMAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:21:09.174Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "config.py", + "DocumentMoniker": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py", + "RelativeDocumentMoniker": "config.py", + "ToolTip": "C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\config.py", + "RelativeToolTip": "config.py", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2025-10-19T13:18:24.643Z", + "EditorCaption": "" + } + ] + }, + { + "DockedHeight": 126, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{34e76e81-ee4a-11d0-ae2e-00a0c90fffc3}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..bb7151a1cf45522c66c62db22db86ee89240f56a GIT binary patch literal 90112 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 literal 0 HcmV?d00001 diff --git a/__pycache__/app.cpython-314.pyc b/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34df76fadae63d10ebcf50d93ed8219f70091cb7 GIT binary patch literal 1318 zcma)5OK%%h6h8CvJnXopp-x-UI;9Pb)lg7nDHW}dAR)1z4KT6W3+ zT;|DNU;Hcs{K1`gsblcsLlIyHJ_l2%Ksd5OD4;J^#Ih7h1s;l_KD(e#*sGd#sV#GQBmC;ld&&M3> zK4q#)*dt$q>&#@DP1{L&V@P5s8=s1ycpGU z6W!_6`8b}~(iq+nh|m}N5`j1p&Frm&8KX-R3{&7w>EDX#nwh!zDL@NvW0u!cj87#N zCpEP+zRd!@50|6w99)B|V^Rm_I19E|fD1TF{;a=!OS%BIP|W_xIroYJQ&t@-*hG+8 z_T0AJK_s>s%vj%8BdZ(hD<7F3V@RX-?I0xH=C<~Z)$3h%yw3L3`2{OzhIW@0gSpS< z7aY1p9oOP+eQtiCOM}4bpi`8X*0vqWx0n*KSgP&$T`NRom2Z(ok7r$(rw@C z60h+kZH7#FY273b&gudrE)DNylH6{T+&6Aw= zX$OZwebR9HwCCGy$kM1wI1wviM$@NONQvb*O!E8gPw)cI0lT^UUhR_rb!#8Ay0%*j zyuRP0HJ|pppceH=qJ;gP<5?}z-D=kO%zIxm?RM8|^&R@Y|0W9Y%MTd-97}>AJOlk1 zWS_&#b2x{e69d%DUin*ZM;d}OFm{b2$o~fU{jCGIcx-?m4bl(Nd&>uqoA4gpd3b04 zo5ReN$KfHAhM*q7^zSe|%uWAbd~f`C`!Kigzm5cg6*?$~@ literal 0 HcmV?d00001 diff --git a/__pycache__/config.cpython-314.pyc b/__pycache__/config.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..101b1ffbba092d4fab03a61aa9661c4140404676 GIT binary patch literal 1033 zcmZ`&O=uHA6rR~^{x(V5NPlS6{zMQ$!P-*P)FN(^wB4Fy<0L@}X@{6>YcR>CyOTmZ zMJOJ;C|)dHEMBa);>F@YJ$ek}5=I2Yli;Bc!K<^IRCCEYy!qa~@BPesJJWq00Wi^j z{l51B0`S8yPKED))*=Hnun7>905MKZf~y?iCcp+a1?D@n2`~hv0J4k##Lsi>kHmuD z1>m>-G|ZSEQddFEy7@hJ3bz4uqVY_lu2gapLQNfrB7#G!CrC?w; z#ygcvq2uYtcq^~zq>wKuC6&23Rj0OX#n>+$N!*Tzk>F}Lx{gC)Qd|-fVVpt|9q)1^ zkr=#%qjE@EmV#nZl4A+2k8P9+5qagbKWiwwlv<%f80#cM@>!fAM9bf;5JksW^D=tN z_zURu;6gg3E1I4bbH#iqt*aF+tE4rhtm^5lLPo#O+GW>hUl$j5v+1lk-Am=FW@Q;n zWn(~p$kZe7O&Hssdl`5UI9P9-ovDvqK7vQScmB8j<7i`Utv-9}^K8@Qc@lUWc)H$j zP1J?S19;$j?SJJzlp4M(^{J~zJI7}}j=mrL6lesZ^=q*c3v|Zei3M2CojAb7={oOg z4h}z;o=N-aVYM+Bs70IJk=k0*J+K$n&Y$+==e1#msjdBXG|Q>OynUNDZV()c?N!~- iCYfnG4}FX&Ru;l9!1)!7e+RBT&mZ0ay)D3$8T%KHSMRa_ literal 0 HcmV?d00001 diff --git a/__pycache__/extensions.cpython-314.pyc b/__pycache__/extensions.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a73a48de298261a6a3ae482f0df2f94f1aadb99a GIT binary patch literal 241 zcmdPqhWH73&pL-r}&y%}*)KNwq8D1e(VP#KrtT;sY}yBja5L^@ptd%`r_(MeIN^01Z4p A7XSbN literal 0 HcmV?d00001 diff --git a/app.py b/app.py new file mode 100644 index 0000000..2078a35 --- /dev/null +++ b/app.py @@ -0,0 +1,67 @@ +import os +import logging +from flask import Flask +from config import Config +from extensions import db # import db from extensions +from sqlalchemy import create_engine +from sqlalchemy.exc import OperationalError + +# --------------------------- +# Initialize Flask app +# --------------------------- +app = Flask(__name__) +app.config.from_object(Config) + +# --------------------------- +# Ensure database exists +# --------------------------- +db_uri = app.config['SQLALCHEMY_DATABASE_URI'] +# Extract database name from URI +db_name = db_uri.rsplit('/', 1)[-1] +engine_uri_without_db = db_uri.rsplit('/', 1)[0] + +try: + engine = create_engine(db_uri) + conn = engine.connect() + conn.close() +except OperationalError: + # Database doesn't exist, create it + engine = create_engine(engine_uri_without_db) + conn = engine.connect() + conn.execute(f"CREATE DATABASE {db_name}") + conn.close() + print(f"Database '{db_name}' created successfully.") + +# --------------------------- +# Initialize database +# --------------------------- +db.init_app(app) # initialize db with app + +# --------------------------- +# Configure logging +# --------------------------- +os.makedirs(app.config['LOG_FOLDER'], exist_ok=True) +logging.basicConfig( + filename=f"{app.config['LOG_FOLDER']}/app.log", + level=logging.INFO, + format='%(asctime)s [%(levelname)s] %(message)s' +) + +# --------------------------- +# Register blueprints +# --------------------------- +# Import blueprints AFTER app and db are initialized +from controllers.file_controller import file_bp +app.register_blueprint(file_bp) + +# --------------------------- +# Create database tables if they don't exist +# --------------------------- +with app.app_context(): + db.create_all() + +# --------------------------- +# Run the app +# --------------------------- +if __name__ == '__main__': + app.run(debug=True) diff --git a/config.py b/config.py new file mode 100644 index 0000000..1300c5a --- /dev/null +++ b/config.py @@ -0,0 +1,14 @@ +import os +from dotenv import load_dotenv + +load_dotenv() # Load .env variables + +class Config: + SQLALCHEMY_DATABASE_URI = ( + f"mysql+pymysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@" + f"{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}" + ) + SQLALCHEMY_TRACK_MODIFICATIONS = False + UPLOAD_FOLDER = os.getenv('UPLOAD_FOLDER', 'uploads') + LOG_FOLDER = 'logs' + DEBUG = True diff --git a/controllers/__pycache__/file_controller.cpython-314.pyc b/controllers/__pycache__/file_controller.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29e4c7de2eeb0eadf30ec1b37f47d85d7b0de36b GIT binary patch literal 4085 zcmc&%OKelw89w*nx8v)?PQuGz8VE6gBupZh7(__G;7k#?mylW1V7c~<@zk-+xz~t9 z8a1U=n|3o9sZul2NE4~ml##mVrV@Qfon$s`SB?S-xYp{r__xu`@h0 z>Y_)=e_sE2_}uUNzd!wfHZOtlqc5J_xB{(zVaF;Cv+;CVGCo(rlG^6G;4*L8g zpAb`5Z{`-JHyd%DSpIjyz7V2xMywXE?st?78-nzoiTfu=Q~7p{?7 z)&!f@gk`RW#M(c{yIzVpbk9Vorc`OMtm!VQ+^i`oG~QAx<>Jho?opL;J~LA+DY`FL zqf{wtnQXNh6JRELOEG6^)qGa7I(em}n4K7>`>$3@m26(gpT|91xKrjk)p^%ojg9MK z>hhH-@N>;7+KozH&27CfA#Ugh@b~ne>@)8sGD+L>Df8j&0cebZUp`349+I{o0??58 zK@Nd}MHYtno>%N5lOwwfZ?sjCc3Qm@-e_Bq#b$3mfG5p>i*70ZHfQMWw_%bBe0A1O zUK6TZy4{+2le2(WlHcL6oGstT`vipTbwG z3h5ozSgPp_tTCX5XG(xO^44DaT3$LGu{@{j(^}uY#z%?7tbYRog18QH((Z3Yq=b( zovD>{zL?j=YF4{3A225sN-H!Ty%dwE2=~+-xV1_VDb$4n&RnHDQ!MCWtp=0d0H5wBsKoNGGsg&{x)!o*Q z&^blL3q+ylsk8C)RaK#CdOSZ{ET`2hHrw{mH?rA8~I z5-wu5*%}zA&gnkW6{qMyI0r$f{vFH$X^8EPV-J1p?{|L?c`tI`*ZU~6Yk9JMXtcgN zz7aZk?@B#%rtUxUSn7J`?Vr58JpDjAuqZwb@7oObu7`V9zV{$}q8@tv9{0xse>(j8 z!+$uk8GmCv{ziTDoAvgKi_S-(J@5U&Bq>f(?%t3^s`934Zy^PyC(F2=6%d$Su9o_S3fIz{<^)T)pe?eRuyO zscYHu%i)!qzc>yXZ%F-juhgZX2kxQ&G#s$v-)ay1#5+9`edNOl4(wW=@9coEHav7T zCVbMvLHm=K1MGZg5T9o76okAud%t4-v@TpoOy$fV0s9bwh+x5I2u2sk?pFkjlpS!` zYG$U1MUyHw%^fl)3Pym!{aKMAL^Y9wX93D%%}#SEJDgZ!7{+ALQXWQSJJ8rv=F@g~ zNg)om6;!z?ejAmW?vxH$3#M$cH{H@X%rh#xs{9xP6PeXbRCZGgVe^6W$lh{Ai_TPP z<$UpH@Rk_v+p=mVt7+NXjaiVCdEW&^i<w1G?oot00yby0oX~qH>LgS z(*8~9;JS2hrLZ9lEQ+5=A(JO3>bqax2#wwwu7^(7{ih#GJC?&A?0s+VZ?yZ;sk-~r zmydnn7X12F##e^xU5DrJ&Q#pt11U0k4ZTO%av_X0O&!(E$ zaJMNSq;23oPbq-{u9vDA27Fdts%CCe%~;(;0gnMe#sgc(si~m7#}4cj(31v9raC&32WleL|j-K z;jkTdfYqJn5*HIwiRWv=U)d9YCfJIx73(1-GQkXSx+S*TP{rqF#fB>P@+1?W%1?3I zqIJ_LX$+REOxdY!Q?!Ppmqlx_%8fzxFSEJ{stzMs8%Q(~_*Nv&2hOpy-U6W+q@5JC z$pGQ=!ZB|Et_Pe{OxJrYfSLa!v;u4xJSNdK3kCt^#5^Fhbm6{x4-204p40X2u?^|W z$31l^QFkZ45^ldvx`6rZot=Bg`@ZpS2)`N{j|i*X95h!W4zRIKx)U6jz(A&mi5SHP zH@L@gMkYlV@AOVc;BFNm^BiFLgxNE)Mn+D2COte`f#0nTSb3m9D<*U9Os1TjRWcch zu}*i;N=-A8HzrdQxkvGRJ|a)S5>v}g!H%_(a+;omF@&P}TQCiQ', methods=['GET']) +def get_file(file_id): + try: + file = UploadedFile.query.get(file_id) + if not file: + return jsonify({'message': 'File not found'}), 404 + + return send_file(file.file_path, as_attachment=True) + + except Exception as e: + logging.error(f"Get error: {e}") + return jsonify({'message': str(e)}), 400 + +# --------------------------- +# PUT — Update file +# --------------------------- +@file_bp.route('/file/', methods=['PUT']) +def update_existing_file(file_id): + try: + if 'file' not in request.files: + return jsonify({'message': 'No file provided'}), 400 + + file = request.files['file'] + updated = update_file(file_id, file, current_app.config['UPLOAD_FOLDER']) + + return jsonify({ + 'message': 'File updated successfully', + 'path': updated.file_path + }), 200 + + except Exception as e: + logging.error(f"Update error: {e}") + return jsonify({'message': str(e)}), 400 + +# --------------------------- +# DELETE — Delete file +# --------------------------- +@file_bp.route('/file/', methods=['DELETE']) +def delete_existing_file(file_id): + try: + delete_file(file_id) + return jsonify({'message': 'File deleted successfully'}), 200 + + except Exception as e: + logging.error(f"Delete error: {e}") + return jsonify({'message': str(e)}), 400 diff --git a/extensions.py b/extensions.py new file mode 100644 index 0000000..3291920 --- /dev/null +++ b/extensions.py @@ -0,0 +1,4 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 0000000..6146d68 --- /dev/null +++ b/logs/app.log @@ -0,0 +1,17 @@ +2025-10-19 22:39:28,753 [INFO] WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://127.0.0.1:5000 +2025-10-19 22:39:28,755 [INFO] Press CTRL+C to quit +2025-10-19 22:39:28,759 [INFO] * Restarting with stat +2025-10-19 22:39:29,594 [WARNING] * Debugger is active! +2025-10-19 22:39:29,603 [INFO] * Debugger PIN: 856-154-652 +2025-10-19 22:40:58,654 [INFO] File saved: uploads/dff289d80b884376930c3b830d1f35c2\136890046ad448109786851cb512836a_174836.png +2025-10-19 22:40:58,662 [INFO] 127.0.0.1 - - [19/Oct/2025 22:40:58] "POST /upload HTTP/1.1" 201 - +2025-10-19 22:41:22,007 [INFO] 127.0.0.1 - - [19/Oct/2025 22:41:22] "GET /file/1 HTTP/1.1" 200 - +2025-10-19 22:41:39,067 [INFO] File updated: uploads\70edd663a3bc44f397e74a6c8e0bb250_174836.png +2025-10-19 22:41:39,070 [INFO] 127.0.0.1 - - [19/Oct/2025 22:41:39] "PUT /file/1 HTTP/1.1" 200 - +2025-10-19 22:41:48,250 [INFO] File deleted: uploads\70edd663a3bc44f397e74a6c8e0bb250_174836.png +2025-10-19 22:41:48,251 [INFO] 127.0.0.1 - - [19/Oct/2025 22:41:48] "DELETE /file/1 HTTP/1.1" 200 - +2025-10-19 22:49:57,691 [INFO] * Detected change in 'C:\\Users\\Admin\\source\\repos\\flask_file_upload_mvc\\app.py', reloading +2025-10-19 22:49:57,905 [INFO] * Restarting with stat +2025-10-19 22:50:00,131 [WARNING] * Debugger is active! +2025-10-19 22:50:00,138 [INFO] * Debugger PIN: 856-154-652 diff --git a/models/__pycache__/uploaded_file.cpython-314.pyc b/models/__pycache__/uploaded_file.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67ba8d58298f251db8ae0534bced01170cce49bf GIT binary patch literal 832 zcmb_azi-n(6uz_b%Sj+<)d;eH3SzL3Dnx?_QH2B%Q8Q3ghHg$yPJC&tp6zgVMr6x? z7`l|Qv}%WTgsp!}hUg>~nAi}lSm7>iS`bnv-f;fjyZ65Lz301o^-2~eF0@+@d+54AYX)0fm1|E-+|?Ozo+ zyfRA)KIbw16HnGk@|=~Di%5(7TAzfDi`|At@JqRpT%UTrLkDOR4;s?X1Q8)lhu}|O z#mtKgLV@FBghUo0KXfCaa2}yokweaI3JCQ)$~f@?9E1o_wSAGQha~a?k!}VYuVX4S z&lRZ`oO;2!$n<1;RW1yLP~YJjqJ$9R4)?mq;WDigam*xJMzWo#<%njzX0I_!nf=7| zy})K+M7!9gxF0gRM;x{(g-Et&G9&U|cWo&d6K2N|>`v|%`U9%|{Nzxthc)E!4vdZ5 zc6qD({{C)lr}nWjGVTqZjteu}gRQ~d>|uGoe6)CQ8R-Ztsnlz7EVh%A1?alpJVVDVCt&y}9IyP7LbFG(aaOYwRi)9cbz?|~`s YU55~U2IbR~4r@|cb*K6hNI0qd4Qv3pqW}N^ literal 0 HcmV?d00001 diff --git a/models/uploaded_file.py b/models/uploaded_file.py new file mode 100644 index 0000000..0e439d6 --- /dev/null +++ b/models/uploaded_file.py @@ -0,0 +1,7 @@ +from extensions import db # use extensions instead of app + +# This model represents an uploaded file record in the database +class UploadedFile(db.Model): + id = db.Column(db.Integer, primary_key=True) + filename = db.Column(db.String(255), nullable=False) + file_path = db.Column(db.String(255), nullable=False) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..a2fbb496ea1102651203c1551504362dea0cffe3 GIT binary patch literal 522 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 e Date: Sun, 19 Oct 2025 23:40:48 +0800 Subject: [PATCH 9/9] feat: implemented file-upload --- .gitignore => flask_file_upload_mvc/.gitignore | 0 .../.vs}/VSWorkspaceState.json | 0 .../27285a50-d78a-45bc-8587-71ceed15b967.vsidx | Bin .../38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx | Bin .../7716003e-af54-4dc2-8aea-99215f903983.vsidx | Bin .../917f158e-4d76-47b1-8689-f1817d69a700.vsidx | Bin .../be2fea4f-3e12-4e63-931a-b796639777c8.vsidx | Bin .../.vs}/flask_file_upload_mvc/v17/.wsuo | Bin .../v17/DocumentLayout.backup.json | 0 .../flask_file_upload_mvc/v17/DocumentLayout.json | 0 {.vs => flask_file_upload_mvc/.vs}/slnx.sqlite | Bin .../__pycache__}/app.cpython-314.pyc | Bin .../__pycache__}/config.cpython-314.pyc | Bin .../__pycache__}/extensions.cpython-314.pyc | Bin app.py => flask_file_upload_mvc/app.py | 0 config.py => flask_file_upload_mvc/config.py | 0 .../__pycache__/file_controller.cpython-314.pyc | Bin .../controllers}/file_controller.py | 0 .../extensions.py | 0 {logs => flask_file_upload_mvc/logs}/app.log | 0 .../__pycache__/uploaded_file.cpython-314.pyc | Bin .../models}/uploaded_file.py | 0 .../requirements.txt | Bin .../__pycache__/file_service.cpython-314.pyc | Bin .../services}/file_service.py | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => flask_file_upload_mvc/.gitignore (100%) rename {.vs => flask_file_upload_mvc/.vs}/VSWorkspaceState.json (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/v17/.wsuo (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/v17/DocumentLayout.backup.json (100%) rename {.vs => flask_file_upload_mvc/.vs}/flask_file_upload_mvc/v17/DocumentLayout.json (100%) rename {.vs => flask_file_upload_mvc/.vs}/slnx.sqlite (100%) rename {__pycache__ => flask_file_upload_mvc/__pycache__}/app.cpython-314.pyc (100%) rename {__pycache__ => flask_file_upload_mvc/__pycache__}/config.cpython-314.pyc (100%) rename {__pycache__ => flask_file_upload_mvc/__pycache__}/extensions.cpython-314.pyc (100%) rename app.py => flask_file_upload_mvc/app.py (100%) rename config.py => flask_file_upload_mvc/config.py (100%) rename {controllers => flask_file_upload_mvc/controllers}/__pycache__/file_controller.cpython-314.pyc (100%) rename {controllers => flask_file_upload_mvc/controllers}/file_controller.py (100%) rename extensions.py => flask_file_upload_mvc/extensions.py (100%) rename {logs => flask_file_upload_mvc/logs}/app.log (100%) rename {models => flask_file_upload_mvc/models}/__pycache__/uploaded_file.cpython-314.pyc (100%) rename {models => flask_file_upload_mvc/models}/uploaded_file.py (100%) rename requirements.txt => flask_file_upload_mvc/requirements.txt (100%) rename {services => flask_file_upload_mvc/services}/__pycache__/file_service.cpython-314.pyc (100%) rename {services => flask_file_upload_mvc/services}/file_service.py (100%) diff --git a/.gitignore b/flask_file_upload_mvc/.gitignore similarity index 100% rename from .gitignore rename to flask_file_upload_mvc/.gitignore diff --git a/.vs/VSWorkspaceState.json b/flask_file_upload_mvc/.vs/VSWorkspaceState.json similarity index 100% rename from .vs/VSWorkspaceState.json rename to flask_file_upload_mvc/.vs/VSWorkspaceState.json diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx similarity index 100% rename from .vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/27285a50-d78a-45bc-8587-71ceed15b967.vsidx diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx similarity index 100% rename from .vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/38b5c44a-e696-40b3-8292-0eec5c49b1ff.vsidx diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx similarity index 100% rename from .vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/7716003e-af54-4dc2-8aea-99215f903983.vsidx diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx similarity index 100% rename from .vs/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/917f158e-4d76-47b1-8689-f1817d69a700.vsidx diff --git a/.vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx similarity index 100% rename from .vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/FileContentIndex/be2fea4f-3e12-4e63-931a-b796639777c8.vsidx diff --git a/.vs/flask_file_upload_mvc/v17/.wsuo b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/.wsuo similarity index 100% rename from .vs/flask_file_upload_mvc/v17/.wsuo rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/.wsuo diff --git a/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json similarity index 100% rename from .vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/DocumentLayout.backup.json diff --git a/.vs/flask_file_upload_mvc/v17/DocumentLayout.json b/flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/DocumentLayout.json similarity index 100% rename from .vs/flask_file_upload_mvc/v17/DocumentLayout.json rename to flask_file_upload_mvc/.vs/flask_file_upload_mvc/v17/DocumentLayout.json diff --git a/.vs/slnx.sqlite b/flask_file_upload_mvc/.vs/slnx.sqlite similarity index 100% rename from .vs/slnx.sqlite rename to flask_file_upload_mvc/.vs/slnx.sqlite diff --git a/__pycache__/app.cpython-314.pyc b/flask_file_upload_mvc/__pycache__/app.cpython-314.pyc similarity index 100% rename from __pycache__/app.cpython-314.pyc rename to flask_file_upload_mvc/__pycache__/app.cpython-314.pyc diff --git a/__pycache__/config.cpython-314.pyc b/flask_file_upload_mvc/__pycache__/config.cpython-314.pyc similarity index 100% rename from __pycache__/config.cpython-314.pyc rename to flask_file_upload_mvc/__pycache__/config.cpython-314.pyc diff --git a/__pycache__/extensions.cpython-314.pyc b/flask_file_upload_mvc/__pycache__/extensions.cpython-314.pyc similarity index 100% rename from __pycache__/extensions.cpython-314.pyc rename to flask_file_upload_mvc/__pycache__/extensions.cpython-314.pyc diff --git a/app.py b/flask_file_upload_mvc/app.py similarity index 100% rename from app.py rename to flask_file_upload_mvc/app.py diff --git a/config.py b/flask_file_upload_mvc/config.py similarity index 100% rename from config.py rename to flask_file_upload_mvc/config.py diff --git a/controllers/__pycache__/file_controller.cpython-314.pyc b/flask_file_upload_mvc/controllers/__pycache__/file_controller.cpython-314.pyc similarity index 100% rename from controllers/__pycache__/file_controller.cpython-314.pyc rename to flask_file_upload_mvc/controllers/__pycache__/file_controller.cpython-314.pyc diff --git a/controllers/file_controller.py b/flask_file_upload_mvc/controllers/file_controller.py similarity index 100% rename from controllers/file_controller.py rename to flask_file_upload_mvc/controllers/file_controller.py diff --git a/extensions.py b/flask_file_upload_mvc/extensions.py similarity index 100% rename from extensions.py rename to flask_file_upload_mvc/extensions.py diff --git a/logs/app.log b/flask_file_upload_mvc/logs/app.log similarity index 100% rename from logs/app.log rename to flask_file_upload_mvc/logs/app.log diff --git a/models/__pycache__/uploaded_file.cpython-314.pyc b/flask_file_upload_mvc/models/__pycache__/uploaded_file.cpython-314.pyc similarity index 100% rename from models/__pycache__/uploaded_file.cpython-314.pyc rename to flask_file_upload_mvc/models/__pycache__/uploaded_file.cpython-314.pyc diff --git a/models/uploaded_file.py b/flask_file_upload_mvc/models/uploaded_file.py similarity index 100% rename from models/uploaded_file.py rename to flask_file_upload_mvc/models/uploaded_file.py diff --git a/requirements.txt b/flask_file_upload_mvc/requirements.txt similarity index 100% rename from requirements.txt rename to flask_file_upload_mvc/requirements.txt diff --git a/services/__pycache__/file_service.cpython-314.pyc b/flask_file_upload_mvc/services/__pycache__/file_service.cpython-314.pyc similarity index 100% rename from services/__pycache__/file_service.cpython-314.pyc rename to flask_file_upload_mvc/services/__pycache__/file_service.cpython-314.pyc diff --git a/services/file_service.py b/flask_file_upload_mvc/services/file_service.py similarity index 100% rename from services/file_service.py rename to flask_file_upload_mvc/services/file_service.py