From d49b266d966afb58d7a8c02945c55d61210416cb Mon Sep 17 00:00:00 2001 From: marwin Date: Fri, 2 May 2025 16:48:00 +0100 Subject: [PATCH] User Profil Fix Versuch 1 --- __pycache__/app.cpython-313.pyc | Bin 70320 -> 74056 bytes __pycache__/models.cpython-313.pyc | Bin 25788 -> 26763 bytes app.py | 180 +++++++++++++++++++-------- database/systades.db | Bin 131072 -> 131072 bytes models.py | 13 ++ templates/admin/update_database.html | 46 +++++++ templates/profile.html | 39 ++++++ templates/simple_profile.html | 75 +++++++++++ update_db.py | 65 ++++++++++ 9 files changed, 367 insertions(+), 51 deletions(-) create mode 100644 templates/admin/update_database.html create mode 100644 templates/simple_profile.html create mode 100644 update_db.py diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 621e517bb95856a81c62c1f5db4e9afe0cf9643e..764f5e3e50f64d9f3f418827bab33cd17e4b20d0 100644 GIT binary patch delta 11486 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 delta 8501 zcma)A3w)H-vEQ?s@7rhIn@zHLZ31~LNl1W%5J-4~l8^*g;savSCD|m~JUP1o32Fda z1ua52$||V56ubIB=&$m2> zy8gbuzkJohEe2h^bA&dKsMobf1jA1a!ZQk~Aja0U4D8>Xy+u zjYZfXqh3v#uu(=|0NNy@bge~rP)7G?P5PhP?uH2bLgw{=#6vQA6VSslB07t(Sw_Wx zw#aBTphskM2+*T48Upl78O7@@!d4kA)tmH>*;>GcZ8Gl{dXunSMiR*P$mk20+aaTP zgGFF6S_s3f!^a-4N#*~z!!_6^6gSpilTv7_ezgMZWqWjmJoZG%#{8V zn?cAt=^t^Sge+p;#h)firB}??w4`1-Io>IfGt#*1w?c?d8qRw`Nr<$2a=em+vR@Z$ zAO<$I@Izvfj8orGkp%W(@wdwDDz>pPja{3rCC{@ToG(kS&gdoKDS>d=^fp7aiuIS) zvG0#%vFTQQ#L7r{GRziUsAPF1Nz7YoBJ%(+YT@+J*{D+Z5AQ6FB1$K3IdWuVcu?2s$0;k>% zkX#6utDMc8^V#&Pq9P&Ve5B=k+|2WlF_+aL3A)YUS9J=lew%KKZd=%vucU0e7`3CJx#(zO%&^zn=R1App*UY+#Nz63@X{Sd5@54$vppnQtMN9x*W9DSug!z z;Sw_WW0?2p*E(G;M_X-Md%c5R0FDdWa=<{Jy4CME{S>$>r1`gtL>~r26dLIhAmUTm z`U5(4GRMfevjpZk8qJ31>)G)f9s7K5=8xv)79|qGQqQKa zI=18mBU@K$loz~N9?Bm69F=KR%9V+1Xm7qehZ})1m1<=&@RQi=v(YT`*~x6#`^oHB zW(+&-(Xp3vqFG0`hBY2Y=Efyd8k8V@;annXwi^E*(fGjDBqU(3HUm87Ki09qNYdEO z#VLG)2R_%b-z+x5rdoC^Cz;h&B(vQS(81}=R+U~Cbug9CA2ER5au4)u97OyeA z-E>d24iA9D|%LVW77L$(%;LNF%VPYjhWXUGjC9nC38+L_}y*8DuoaY1|_8J$$cu5f~OFUJ?x(8-97`w%RSV&l#Q%-xuB= znl~WkpD^{Bq`0pIWz?(-r89>Gg%Cb$P{hV2`+Qa*{<9XH z&nZ1WanAV(S;d2?8GE~qPZ~%qJU=e`a-XSZgQU7xK04^^_f>oB+aG%!M+Cd#IS7$2?1<6kd+v!+M2AHP7B1Qn?5@8b??7-OG z5GO_f;|s!$HnadEp)px!1jd)}pN2{E8XL$oO!=-zUZ-!AUVd>85nh3<`r!5S=^7pG z+ICu7kY50IZm6k*e9DrY$&m@5?kfCu-2=Md)`+a~!Aa5s&SqtL9I$;#xaJ|FI@mdM z1!ua_Djl5;3tQ?ovO8vnYfuqvY-YtRl*F+kEqQ_kSPJPv%U)FqT1uB82{uF2LX%Kc zD%Ya5hqBWhVgYKR$;gj%)H~g^qg|sW;9HGB$7n1{pJU&4%rJ9>!AirMD%M9D&#G1@ z3uz!3E78^Gl*+Fatjt{`%4?I@bM9CY&n};h3k@`}bP&&xhTLxuqGm6wDJBBDxF%i5 z26m|ww)S0B4EAB4f;wOepT^zP-r3mXcCo*AC5pUuO=RKgQzoDgRimW3$?med-PEUQ zakSBVJV^FnY3+vj@XTw4k@V_*%*7P$m^?5UDw{`cC@)^4>~x4 zqy>miS4SOox1+w+?!F;9HsaiBp{?ERa9J%k1riknt9Tq91Jxrl7}q?6*n{X5wsg~Y zh|Zc#+1=AoaxxO`*;Jh8J)s17+`v*8!3}V=H?-4MuutoE3!fHzI((*Z)z;hHcFIGx z3%OdJ+x&53CN2&^vr!g|=dvy>h`|Ghg;^d<(%*(#LG^ciKv?_MiPD+}&xhEiBC`ky z57o3AG74G@BM9xRz!aQ;Jf^deI|s;eU{|9v!PUiV-{yos@+9`eG2dpR`o;p*x62fM z!!ut9cjr@P-jYG)vpHLG^i`noFj|;N*zbGlrNJ#1m6<^c7vZkB+j48zO-I8n{jxA| zJW60@gIPQ&xLFuNI-gD3nxnIUzz4X)0hYRRq4d($ajFHu4MsVEiuj?8+BBM~QBxVt z1zY=#Ym(TLwrCm7$g%OS4`v3pOXIhz93{D3e9y%QE0FL#=d=9XCiYB^NvsCm-<8tI zo*k;}pq(>-dr0knl;8=(mB?vMOWB$yQUXV?`-!x|TMFTJbCKKyBoHue6J`@#z^*)z zF5C^nFe!28z32Ixw?%SUv*kSlH>Dm1)N|MX;2dm<- z#PUjI4e{w{d%K&zrMTz><~o=sG{S6`^!&kVM43m}aF>x6R)77)A`B0m!P>>c)QCRu zmo{Fc>rp-KVHGHrCjaAU19A(1K;3O}w$%G;(wL_Oz7)x3^u7%iZ%|y6ihlKgsvBeL z(=F`DZo?dE0Ff-R<*Y`x7um5quv@rdHLOlCh$Yz)wT`vaO?a> zyaQ)jkjI_kC)kQ`FHQs#j1?R)lOa}hWI{Nq@u_b#G1|s9AIT70!1GAbkuOvc{v<#Z zc}QB>(c}3^K_*wu`;WMa+S}@ypd(*9KEccj$ryu|pbY|>)f=bgwyO!$%vjdh8)@b# z!=uYR7^R=>?TsUpo$Q?;+y@5qN`LLWEuzV;{J8wXe|)P?0;V*HU2&qtzaRiqSQQC{gNABB3<~)@z zZi0QTsiZxpo>G~EHEZm0w(N9TpeDR>Hg2LC&w%IFSV>Ul_kUEaVy92X=y{3e8<(>S zr&D!52gz|Ea38O*&_7wE>@yw8Kmpo!RxUuVoK5>t0rG2s$3% zX~p*k2mue%MzoRV4o@4*7@tTTt?g?ZRLy?(y4esk=^F(bdOb~e6l9i3nm-jONhX{9 z=6aIFPQ7`Lz<}K-CI9(434H>F(0=^>vk7lmNI5HiYrL=v`0FJ1TWX@-3B%>|Nw(?j z3BuDbewg*Xy+wQmMs$G9ekViN3&S0(`JGf!#J0XuSzN@Y(AqsP!aJ|#5_N@@^Y3uwH|i=>o4Axykc3~(j;wY|@ zki3NC*DUIj@#A0TOI+|o?5=e?TOITaGDLfuYpsLQ!?^2zvK5~c2=4*^fW$r-F=V`m zBI+9*h4ulu@r`bS|05zg=gVYEhK%g=m(iq{m`vXz`J(StC8Zmn&G7na6$>U6+C?Yr{o)FICI_pT}EB`>cRflL1arQz17=%?)T)zd#Rf%mU}$Ap#aH~(BjF75bg2|2-* zel;PlN?Jt!(F4$=N=1k2j7hFoIf*C+5$Ad>rwLwH-$S`}nH~ zy0bV$k}E}jU8#ca0;|5Y3f};uRoedT?F2sCuC>!P_|CyTycQpdRmZCKzt9b_9(Qy$ z?_478`W?)TzU{i!b+z`oI`{T!4CSenI7}>yqcJ zn&gSx>s-(Os)<9~ic22z)M?1v68?tFKOpkH&%?@3hd-=w4Lp;1{0v}`Pu*ds@T%;h z6Foy35}k?`TMhIRG>q@kgX(u6;a#o46Qd=$q`)&zOY#LHs5p4yUMvfM<(= zq>3is{~(+=ZXkpRaR5}F--MD=;vmX2d+rS*IYjUr3?n5%0?Zmb{}V>?L##)r%2OCc z_K`A=H;Vk#^IA07Laul!jU+Wf067|hgcldl(`_Wlyd;ai9iyC#E2vTi3Ld-l5`~5NO%Zu!%-Cy8xnjEqjw`&i3Fe4sU1lpl6nGXNikjM zeMs>$78qgc;jM&Xcc9n=DAq2X(G;`T zpLv*R6qAV_MOU8#;ww?n&NhmNK{4_aBTg}}V?VKJN?P0NJ6jwx>0FovO$yg?&tVg( zI`O@UY*U6OlbjKiLOE$z38UfJp55`p6_ZVJkr{y`b~ps!a1A+;ZYKXFre0PmNhA4s drAnbocwcM&)@1;lAB~H)m#T(Jb*uF1{{zk5va|pI diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index 7136ff4e4667167d2c050d223a4d96400d7ceba4..d03e1c90fcb48b808a6f857fce74613b10e04af5 100644 GIT binary patch delta 4628 zcmb7HdvKK172ms?-DEe}-7I~8N>#c zce%2y-dr5p>UG=+?9L+SDa}B^GnoSNFC<{G}->*gy4mU>EI zea=?XbP(y&Zz8~hIU6>s**l^#?@~g+VJV_!`Ub-z1A{R&GZ+s^!%9Fk_lLuKhb6vO z4*L7!&oSPHJ3Ttp7?lIzP*CD=LE)`1k+%Vi<~G&=Th03ow;~(g32&KiWLw}r=HQ|o zv`@=31)bnFh*)Y^7d&Hey8;-3!xX59#nL(7_?Aun6ssnL|9fNoVU1&5W8 zhp8DnJS6iTWQx*uH(!jXW+_p>;84wE*{Um3!DmB`G0k7Cc}L=hm6)s=qLE%U*j7WHa*Bh=W(5Y7p&*w-sy>7#M^PGv z&2%p@5cuGq`5)JwPOFsgVhdKIrXAKY=NcTBGE(a)I+=uzHGqhaq&Z>Z6kyn+eX`YJxvY} z93)sxu##XDLA7FC$f2NLzDJ41l+XY_LQ9(oZb9(q`Bq}fj&KD#N_O!(Pw_J#dTKxW))ITKqCEh*| zMI%M-l@L1%@G{!Fgg|6tW<kwSqn6jx!e9Pr;wSvieP~g;Cp5E zdf_A!c5=)d?5=XsPGMC}(r^A`fmP6MVH#FkOpZdUufRlV3*8?}n9FMzUQja?j>H|y zUSjMt*jN0ZAf1+v!nqYS*$Wl1RFs;|kSK!Fu)g9~>`Y>&;(e{*G!mv0@OEXd;aOrh z02NgpXF91Oy&i?VRZCVg;ZQl?*lXKw1LjWt+n>9M~Ivq4Uh1E?2pAGcyso1DHIqK>HeiWppElhp*+V%9v&VR8GR1U)K+Hl zI5GV}_==pu30_H<*8YgGP7(8W>ONzJ*O5AX0e)A%6PwB8Cihnb>bCW3mMq8t5-OB9 zNh48gPmAM7CMUQ6@2vljy^g0j6E8KqzznY;ae4;6b+h6Uy{eix&k@{Dkc-gmDa1EN z!MbaDP!z^;Vy_~2n_z)f(ADHJoFXEJP}5=)9mxr1;PIw+*=xe|1I-^W!^=pV{sMYi z>)5k!wAI~l%_Eb6B0*OjzTjM1O@>7HfP`~`FTm0EB76Di58AXhH{o0{Vk-LhQd*x+ z(B$PI>P4jG23%GRu|e!|L4KBaU!_*xnAPYLG&k=?B0fOhr?s>#--PCDv8nma zYxZOzNEj-5avIB2(?}#Jnl3hb;Rq1`5%?IXAujZ6GLjP*8T7Qj&6qvck0E-qN#H6($w@Z#jr2%=)2siw8^XBd8jF^v68rA33RgFof(ybx72|Z$y znnTVuBeTQkmgm`qMBObrwVj(t-}1S5O@9~XscS#kH)!wtji0qK92lV*R5S5yx-%mtiI}v-r(HMV#*v}G(@&#+J%|)4ijo?E= zuM4k{+j^S==}Z*yTSnWzZrJw_^IifG>?~uI8QTjJ?Xl>%^0e z7i~mjws_|4fzR(+?hxH+BQ3WgsG0ck9a82#KFCZ?;7jcC?_=5w2Jhb;9u@kSh+prc z7v+NQ91(*Ol2=YpK_JphJWwmeo-XwA5U-{s`kYCAG>CVXcrl$OS|YL=H-%`L z9D8JavH(R=ir5Gh#qF5n7ZRUKzhHT#tbDxs$hyPp Rj`m&B;N(&#gI5BV{|CVcok#!x delta 3931 zcmb7HeQZG36KPukMRNtYN+GbugNQpZCyJ+ zGPbg*bem8&&|&IOiz?Bo6Wv;kcokh&Z9_;E^sh!6Yxg9icHM{EY0^g7gt|`JIro{^ zY7OnIL%CFunO8}bH3i%u*%6&m6=JpI;59Q&Z#DeG z{0Qu|^uh9>onW{2vL2YQ9ybi)?R*$+S=-qzFxbN7LrC!IxKYpvM&P7v3)>A>Y#x)B z@nNJ5dtDGK+iLE|v8tEnf=UF>SSsr3-xmwm2Ov*DczR(&7a5>HcfiWm`4%8nc zjza|F1QP^@2@(iu(U^Q93G>cPwNpg%6RkKjt3<+Fj;i`-EG#GZK2pgf69Yj%{K@%8 zJ&i)=%Ixq#^>JAAS>W-_Z7{X29(L}igrC_X;BKfeNQIKATLvBgM z)YW?QMs#vjW>#6fs*^OrAMT+Qhh&xt+ZlI4S*HVnwTo7ZWR+~)7#vbrw}HEfZY-bl zOzIEpfPdO5%oUmSO5D8$S8LsP-CD_skx?&IBd(Kbc*Bg#Tgzj3PkJ0ebtB_^2FH7O zHzJ=UPzc%xHWEC6pjy#Nax@%}Pbi6`5}n~+C#o^Lfc{WIml@xQbFW@4NywpCG#um$ zaIdb;L*^7qs&Q;KHa|0)PP)n3V?C}_%3nuvhjC)$xB0S|e z^W;1+JT!dxF=ENNk)}s7M+V~a(-9@aA0?umV3L4tGTbA)thXJgOxS zNCu}Pav;d}&m=ICr-*$uv9l1br-_?D1gbF}#3)TB_&QoIPHHAjsHW_}T4FvU0+^gG zJU^cL_nPM!i>09cCpxQIdN3h#vh7?jo<0qG8i&~ooNsJkF?h4l+kA?)eT(2}g3}0U zX@-3`mXuZFoVJ(ufThXP`+u2@48dCna?AwrCZ|J~(WE2-ajqOgGijFa!wXFgb{?)a zxlPZ~HiFZs51O_x_AH#*UY%<7zQx!@_}hj{_I#2o!lmXdrMZ`V*u2*C5*W3Ed_&i8f|pZ2ZFivpsT-SKDKwC=(@SuobF?{q1IJpPDtEC|c0{GPp$iu-@Z3|Enm{s{K% zQe2{BZ6>bk1W^JT!mzgrtnK!$2bxbre4HBLZGvm%4){**E9|OBfc<^9m|+PQ(|4e8&o*`e9^2#Tf1nJaguRCBns2hw z7t$X5q-Z?aMYKClbM# zZ0o9kvqOUi@(G>wNsg#=x^TjZxN3=JMCu-*mIR1Ld##XooS+njhOe?+DgDSHouLm2 z3ce=3RlANeE042rIskW&$(iX4j38t_kIOa zh;+>7dd(E@?)Y}5xtVm~1Wl>di7LiEPVG6Y*Ntw=YUjynM=7bj?C2?=TJX&?KNkpP z-p!(JsU>@fI2ubNd7Rj@`3bilEpt(*KfwD?GU;M{&@kx_5ZyY1yL+G2$IBhTyZ6{M~m`9|TIPmxFI&l=?m z#R&qzUR#uoJ4z5Cps$b7j)!QBOltXxy;j^j0b8d1hw|CrbDDpNn@I*yPDI4JX?g^1 zPB&Ih(Xf|*nzw4i&z*>}@|{Aua)SQUhR`vl`?LTqg=0?&c}&EwAEOs$PN7_+9rVT& z4@thBMk4wqY1E9M>W9$y5&T|5f=oaWBpzSl*(9DWq8*DyDVmh%5TbZe9qQH+Q^cxp znGjL5N$pdxj;<;8&Bem=5xIxk&{_CbkoZOFro6<;?acSx%|Gb+Uf0>fcMEWGw-vrW H^WXmg4*19Z diff --git a/app.py b/app.py index a0d7e87..fcc686a 100644 --- a/app.py +++ b/app.py @@ -19,6 +19,7 @@ from openai import OpenAI from dotenv import load_dotenv from flask_socketio import SocketIO, emit from flask_migrate import Migrate +import sqlalchemy # Modelle importieren from models import ( @@ -316,15 +317,21 @@ def register(): user = User(username=username, email=email) user.set_password(password) db.session.add(user) + db.session.commit() # Commit, um eine ID für den Benutzer zu erhalten # Erstelle eine Standard-Mindmap für den neuen Benutzer - default_mindmap = UserMindmap( - name='Meine Mindmap', - description='Meine persönliche Wissenslandschaft', - user=user - ) - db.session.add(default_mindmap) - db.session.commit() + try: + default_mindmap = UserMindmap( + name='Meine Mindmap', + description='Meine persönliche Wissenslandschaft', + user_id=user.id + ) + db.session.add(default_mindmap) + db.session.commit() + except Exception as e: + print(f"Fehler beim Erstellen der Standard-Mindmap: {e}") + # Stelle sicher, dass wir trotzdem weitermachen können + db.session.rollback() login_user(user) flash('Dein Konto wurde erfolgreich erstellt!', 'success') @@ -379,49 +386,96 @@ def mindmap(): @app.route('/profile') @login_required def profile(): - # Lade Benutzer-Mindmaps - user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() - - # Lade Statistiken - thought_count = Thought.query.filter_by(user_id=current_user.id).count() - bookmark_count = db.session.query(user_thought_bookmark).filter( - user_thought_bookmark.c.user_id == current_user.id).count() - - # Berechne tatsächliche Werte für Benutzerstatistiken - contributions_count = Comment.query.filter_by(user_id=current_user.id).count() - - # Berechne Verbindungen (Anzahl der Gedankenverknüpfungen) - connections_count = ThoughtRelation.query.filter( - (ThoughtRelation.source_id.in_( - db.session.query(Thought.id).filter_by(user_id=current_user.id) - )) | - (ThoughtRelation.target_id.in_( - db.session.query(Thought.id).filter_by(user_id=current_user.id) - )) - ).count() - - # Berechne durchschnittliche Bewertung der Gedanken des Benutzers - avg_rating = db.session.query(func.avg(ThoughtRating.relevance_score)).join( - Thought, Thought.id == ThoughtRating.thought_id - ).filter(Thought.user_id == current_user.id).scalar() or 0 - - # Hole die Anzahl der Follower (falls implementiert) - # In diesem Beispiel nehmen wir an, dass es keine Follower-Funktionalität gibt - followers_count = 0 - - # Hole den Standort des Benutzers aus der Datenbank, falls vorhanden - location = "Deutschland" # Standardwert - - return render_template('profile.html', - user=current_user, - user_mindmaps=user_mindmaps, - thought_count=thought_count, - bookmark_count=bookmark_count, - connections_count=connections_count, - contributions_count=contributions_count, - followers_count=followers_count, - rating=round(avg_rating, 1), - location=location) + try: + # Versuche auf die neue Benutzermodellstruktur zuzugreifen + _ = current_user.bio # Dies wird fehlschlagen, wenn die Spalte nicht existiert + + # Wenn keine Ausnahme, fahre mit normalem Profil fort + # Lade Benutzer-Mindmaps + user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() + + # Prüfe, ob der Benutzer eine Standard-Mindmap hat, sonst erstelle eine + if not user_mindmaps: + try: + default_mindmap = UserMindmap( + name='Meine Mindmap', + description='Meine persönliche Wissenslandschaft', + user_id=current_user.id + ) + db.session.add(default_mindmap) + db.session.commit() + + # Aktualisiere die Liste nach dem Erstellen + user_mindmaps = [default_mindmap] + except Exception as e: + print(f"Fehler beim Erstellen der Standard-Mindmap in Profil: {e}") + # Flash-Nachricht für den Benutzer + flash('Es gab ein Problem beim Laden deiner Mindmaps. Bitte versuche es später erneut.', 'warning') + + # Lade Statistiken + thought_count = Thought.query.filter_by(user_id=current_user.id).count() + bookmark_count = db.session.query(user_thought_bookmark).filter( + user_thought_bookmark.c.user_id == current_user.id).count() + + # Berechne tatsächliche Werte für Benutzerstatistiken + contributions_count = Comment.query.filter_by(user_id=current_user.id).count() + + # Berechne Verbindungen (Anzahl der Gedankenverknüpfungen) + connections_count = ThoughtRelation.query.filter( + (ThoughtRelation.source_id.in_( + db.session.query(Thought.id).filter_by(user_id=current_user.id) + )) | + (ThoughtRelation.target_id.in_( + db.session.query(Thought.id).filter_by(user_id=current_user.id) + )) + ).count() + + # Berechne durchschnittliche Bewertung der Gedanken des Benutzers + avg_rating = db.session.query(func.avg(ThoughtRating.relevance_score)).join( + Thought, Thought.id == ThoughtRating.thought_id + ).filter(Thought.user_id == current_user.id).scalar() or 0 + + # Sammle alle Statistiken in einem Wörterbuch + stats = { + 'thought_count': thought_count, + 'bookmark_count': bookmark_count, + 'connections_count': connections_count, + 'contributions_count': contributions_count, + 'followers_count': 0, # Platzhalter für zukünftige Funktionalität + 'rating': round(avg_rating, 1) + } + + # Hole die letzten Gedanken des Benutzers + thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.created_at.desc()).limit(5).all() + + # Hole den Standort des Benutzers aus der Datenbank, falls vorhanden + location = "Deutschland" # Standardwert + + return render_template('profile.html', + user=current_user, + user_mindmaps=user_mindmaps, + stats=stats, + thoughts=thoughts, + location=location) + + except (AttributeError, sqlalchemy.exc.OperationalError) as e: + # Die Spalte existiert nicht, verwende stattdessen das einfache Profil + print(f"Verwende einfaches Profil wegen Datenbankfehler: {e}") + flash('Dein Profil wird im einfachen Modus angezeigt, bis die Datenbank aktualisiert wird.', 'warning') + + # Lade nur die grundlegenden Informationen + user_mindmaps = UserMindmap.query.filter_by(user_id=current_user.id).all() + thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.created_at.desc()).limit(5).all() + + return render_template('simple_profile.html', + user=current_user, + user_mindmaps=user_mindmaps, + thoughts=thoughts) + except Exception as e: + # Eine andere Ausnahme ist aufgetreten + print(f"Fehler beim Laden des Profils: {e}") + flash('Dein Benutzerprofil konnte nicht geladen werden. Bitte kontaktiere den Support.', 'error') + return redirect(url_for('index')) # Route für Benutzereinstellungen @app.route('/settings', methods=['GET', 'POST']) @@ -1548,4 +1602,28 @@ def redirect_to_index(): @app.route('/static/js/mindmap-init.js') def serve_mindmap_init_js(): """Bedient die Mindmap-Initialisierungsdatei.""" - return app.send_static_file('js/mindmap-init.js'), 200, {'Content-Type': 'application/javascript'} \ No newline at end of file + return app.send_static_file('js/mindmap-init.js'), 200, {'Content-Type': 'application/javascript'} + +# Datenbank-Update-Route (admin-geschützt) +@app.route('/admin/update-database', methods=['GET', 'POST']) +@admin_required +def admin_update_database(): + """Admin-Route zum Aktualisieren der Datenbank""" + message = None + success = None + + if request.method == 'POST': + try: + import update_db + update_success = update_db.update_user_table() + if update_success: + message = "Die Datenbank wurde erfolgreich aktualisiert." + success = True + else: + message = "Es gab ein Problem bei der Aktualisierung der Datenbank." + success = False + except Exception as e: + message = f"Fehler: {str(e)}" + success = False + + return render_template('admin/update_database.html', message=message, success=success) \ No newline at end of file diff --git a/database/systades.db b/database/systades.db index c9cf76ebf6edc67630f5bc57735751f4a46ccc4d..fc79cc04adb5e3732cfa63b502d97bb4725b1355 100644 GIT binary patch delta 429 zcmZ{fF-yZh7=|xYBq_+np+l)dgcc|3-Q|)tS!@v(p&)`SLI*F&9f`If^jZX$rjx7v z3q{;(!9U<1@K?CFbm?wN9YplyajW{7UHJQMBoeTIHqS2N;pLhc8)l!b54DNh;@jv zAqKWwV!G6++N5S;XC(O`4**c$3c%H3SO0{Ce6FN@yKc}Dz-5L$pbm2t?Wg}sV+&>f zP63=|2M=)ES5$CtsWqEgi$^gxT2UPIS+ZFYK9Fy(aWC>iZge6kc`SP@4x}G4G5k}~ fLX_bD2*o>@I?&g($wE(-$1_8prTVXaM#}paPFQsN delta 46 zcmV+}0MY+|fCzwq2#^~A7m*x80T;1gqz|(Mu>2pgzyuJZ1VAve1c3ZMqL2`Rz^1?f EKzGRzTmS$7 diff --git a/models.py b/models.py index ae14f19..597b234 100644 --- a/models.py +++ b/models.py @@ -53,11 +53,20 @@ class User(db.Model, UserMixin): created_at = db.Column(db.DateTime, default=datetime.utcnow) is_active = db.Column(db.Boolean, default=True) role = db.Column(db.String(20), default="user") # 'user', 'admin', 'moderator' + bio = db.Column(db.Text, nullable=True) # Profil-Bio + location = db.Column(db.String(100), nullable=True) # Standort + website = db.Column(db.String(200), nullable=True) # Website + avatar = db.Column(db.String(200), nullable=True) # Profilbild-URL + last_login = db.Column(db.DateTime, nullable=True) # Letzter Login # Relationships threads = db.relationship('Thread', backref='creator', lazy=True) messages = db.relationship('Message', backref='author', lazy=True) projects = db.relationship('Project', backref='owner', lazy=True) + mindmaps = db.relationship('UserMindmap', backref='user', lazy=True) + thoughts = db.relationship('Thought', backref='author', lazy=True) + bookmarked_thoughts = db.relationship('Thought', secondary=user_thought_bookmark, + lazy='dynamic', backref=db.backref('bookmarked_by', lazy='dynamic')) def __repr__(self): return f'' @@ -67,6 +76,10 @@ class User(db.Model, UserMixin): def check_password(self, password): return check_password_hash(self.password, password) + + @property + def is_admin(self): + return self.role == 'admin' class Category(db.Model): """Wissenschaftliche Kategorien für die Gliederung der öffentlichen Mindmap""" diff --git a/templates/admin/update_database.html b/templates/admin/update_database.html new file mode 100644 index 0000000..2facee2 --- /dev/null +++ b/templates/admin/update_database.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} + +{% block title %}Datenbank aktualisieren{% endblock %} + +{% block content %} +
+
+

Datenbank aktualisieren

+ + {% if message %} +
+

{{ message }}

+
+ {% endif %} + +
+

+ Diese Funktion aktualisiert die Datenbankstruktur, um mit dem aktuellen Datenmodell kompatibel zu sein. + Dabei werden folgende Änderungen vorgenommen: +

+ +
    +
  • Hinzufügen von bio, location, website, avatar und last_login zur Benutzer-Tabelle
  • +
+ +
+

+ + Warnung: Bitte stelle sicher, dass du ein Backup der Datenbank erstellt hast, bevor du fortfährst. +

+
+
+ +
+
+ + Zurück zur Startseite + + +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/profile.html b/templates/profile.html index a243f45..e5700c2 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -559,6 +559,7 @@
Aktivitäten
Gedanken
+
Mindmaps
Sammlungen
Verbindungen
Einstellungen
@@ -632,6 +633,44 @@
+ + +