From 4cc32d32001d951001d335aa258d5af9cb9b48f4 Mon Sep 17 00:00:00 2001
From: deadvey <deadvey@deadvey.com>
Date: Mon, 24 Mar 2025 18:08:06 +0000
Subject: [PATCH] initial

---
 .create_pages.py.swp                     | Bin 0 -> 12288 bytes
 .gitignore                               |   1 +
 README.md                                |  13 ++++++
 __pycache__/config.cpython-311.pyc       | Bin 0 -> 704 bytes
 __pycache__/config.cpython-313.pyc       | Bin 0 -> 712 bytes
 __pycache__/create_pages.cpython-311.pyc | Bin 0 -> 3426 bytes
 __pycache__/create_pages.cpython-313.pyc | Bin 0 -> 2888 bytes
 __pycache__/newpost.cpython-311.pyc      | Bin 0 -> 1704 bytes
 __pycache__/newpost.cpython-313.pyc      | Bin 0 -> 1507 bytes
 __pycache__/parse_post.cpython-311.pyc   | Bin 0 -> 1584 bytes
 __pycache__/parse_post.cpython-313.pyc   | Bin 0 -> 1429 bytes
 __pycache__/rebuild.cpython-311.pyc      | Bin 0 -> 926 bytes
 __pycache__/rebuild.cpython-313.pyc      | Bin 0 -> 826 bytes
 create_pages.py                          |  52 +++++++++++++++++++++++
 example.config.py                        |  44 +++++++++++++++++++
 glogger.py                               |  38 +++++++++++++++++
 newpost.py                               |  47 ++++++++++++++++++++
 parse_post.py                            |  15 +++++++
 rebuild.py                               |  11 +++++
 19 files changed, 221 insertions(+)
 create mode 100644 .create_pages.py.swp
 create mode 100644 .gitignore
 create mode 100755 README.md
 create mode 100755 __pycache__/config.cpython-311.pyc
 create mode 100644 __pycache__/config.cpython-313.pyc
 create mode 100755 __pycache__/create_pages.cpython-311.pyc
 create mode 100644 __pycache__/create_pages.cpython-313.pyc
 create mode 100755 __pycache__/newpost.cpython-311.pyc
 create mode 100644 __pycache__/newpost.cpython-313.pyc
 create mode 100755 __pycache__/parse_post.cpython-311.pyc
 create mode 100644 __pycache__/parse_post.cpython-313.pyc
 create mode 100755 __pycache__/rebuild.cpython-311.pyc
 create mode 100644 __pycache__/rebuild.cpython-313.pyc
 create mode 100755 create_pages.py
 create mode 100755 example.config.py
 create mode 100755 glogger.py
 create mode 100755 newpost.py
 create mode 100755 parse_post.py
 create mode 100755 rebuild.py

diff --git a/.create_pages.py.swp b/.create_pages.py.swp
new file mode 100644
index 0000000000000000000000000000000000000000..a59ea52f33bc00cee98887f6bb422cbf6bc56c89
GIT binary patch
literal 12288
zcmeI2zmF3~6vyY%LBg+4Bt?pcuiy^O>+_K!oN^7=2umDD4uK>NSbN@Cvy#1Q?e1a2
zVQ48S>7Y*<3R;8&e*{St>J$m0NeACIvuhilIUuQs-b&xw**7z9-ut|nlTJ4q%NJ_v
zblfQ`Jo}ZZ-+SKv^}tVa2k$E7Y1g}|uW`?gPbX@*ohwn2I;Q1CT{j44%($63EVUv}
zm)f1E-PUob6>B%u&7RxViPL-cYBL;*NeBpmoe6BFe({?<>exzonFr1n4$;BSzu$R|
z^a=qXAOwVf5D)@FKnMr{A@IK<koM-(EoAgbmetqUdv5BTeacG+2mv7=1cZPP5CTF#
z2nYcoAOwVf5cmiQxSmp9>{99##Q*=#|NeiuPpKEsAJFg6Q|KXd54r<ghf?SVs0Njx
z668Px?S=l{tJGi66KDwe(0=I8JxV=;9zcDl30;Q1h5q?Wsprsr=r+`Zjzcd#MI6v?
z&|~Np6hjT@DD)+?8~SCpQg@*n&;{r#h;w_y`N<;$gn$qb0zyCt2!W5Ez^?!Pq(N7A
zf>1a8prf6B9He@ohs&Ic3ck5PYt(b&1Xncqis!i5^rN`zre^RG4VGv#(Q)W@_2kS}
z6#7Bi87;y-vWe_JpMo{GnKTBC@}*+=68hks1{8$U+KiJZUWLiF96ivjO+@JzzN?<8
zo;*)S=v4jOI<fDB&ebc`I-U5@eAX&d(MgNW)Yfa~X)BAy3~UBrGY@N6Ffp4D=;#^^
zK5TuScNU4;FpL-D(8i10ybZ^;7kC}J%o;V2W<N-;P}I{QvdP2i>y0>y(qSnGJw0&R
z-Jq~Ug??d?+=TLwO}SQaN7tw925sK6;B73fDy+k4&L}FI-@B$Z?3IRnH<r0LC=sWT
z`I%s9F7cXeGA?oEU{tijZ`RDPILz*{f!k<V`)K~`qF+2+tylAkuhACAR;$>uS_jj9
zcLdMVOSzM&0&pKweS<w4P4?zA)GA9Txh;aJ_KYgz_{QhyUmh(cI1BuY^TR_YLh%dp
zw8b_)w8Pb(!--A%Uc7lOP8fLG)^O(GoACNUMPQ$$aePx{;NERzV52RA4QTv3DKCg0
zM_ux8;hawk1>Ig0r=xF`eUEFBTkIyswOKV!6VHtzbzO5pr|jkvy(R}L7Ad>>&Pmul
s`!n~2p~uF3BkQ(7D{mcCG`qjVYn8`?;J}zhze!96r?7n~jWzc0YYlrcA^-pY

literal 0
HcmV?d00001

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4acd06b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+config.py
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..abede60
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+I've written a basic program in python called glogger, it is a customisable, statically generated gemini blogging frontend, it's being used right now. It works by having two mysql tables called " "users" which contains just two fields: userID and username, and "posts" which contains 6 fields: postID (PK), userID (FK), title, content, pubData and editDate, whenever you create a new post, it will add a new record to the posts table and write that post to the gemini frontend. It has a few options in the configuration, to allow for differing formatting to change how the whole thing is generated. I am wanting to add a better text input field instead of the basic python() input, probably consisting of a vim buffer that gets sent to the python program, that could be great! I also want to add passwords for different users and modification of previous posts.
+
+# Setup
+## Requirements:
+mysql-connector-python
+mariadb-client
+mariadb-server
+## Database setup
+``` CREATE DATABASE glogger;
+USE glogger;
+CREATE TABLE users ( userID INT PRIMARY KEY AUTO_INCREMENT NOT NULL, username VARCHAR(255) );
+CREATE TABLE posts ( postID INT PRIMARY KEY AUTO_INCREMENT NOT NULL, userID INT, FOREIGN KEY(userID) REFERENCES users(userID), title VARCHAR(255), content TEXT, pubDate VARCHAR(255), editDate VARCHAR(255) );
+```
diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc
new file mode 100755
index 0000000000000000000000000000000000000000..9c56a0131992de34a4deff902dc3e62c8bd3da02
GIT binary patch
literal 704
zcmb7CF>ljA6h1dj?3|ORDM=|32%~UA2e1H%A%Y4CDlwF*A~0}^b?Li07Iqx@oL2GV
zf5FUz_%|KHO-M{^k-Bw2Jf{hwV&ds^ci+A5eecuVeQ7o+!T2@!7JRM{@}mUnFjkw3
zr?~k<fN%l^H(-NrK!sPp<R(;k6>7W&7Pr9WHq?0?D5v0X2O0yi+swBD8HeMr?|D&j
zETU1OvV7A!6{&{_FNl&LkZIm#;IY_aA6${S>~){L$shbz`~)<q>wkJ^Gfk3AR~|in
zqOEn8JG9qx**nT!(&u|FJ8&m5jYSlWKT<ZJ`CHm^kI<h4cQ|v|;fmeEqNC|B3e`wL
z-(|1X_3um0^~`}#nY#}mY9Mo;=G)g>E=#c2;ci3Q3Tgf{jkI+phfBK-2s}DT&{d{e
z6ZGOMi6%vsq`F;V<%eTG3uB3{r8dj!)aF#lRNE7w)LD{(woye4g_62kX8ef=q`wqf
zDR-CPpX1J2_iyr7a#8++%lqCaiKPcpz^R;h#|g;w>meAQgu%nf?9zS~CoqlVUb>A%
z<quK=oE8<sFupr?3wus)7uLLWuW;t=7e#B{xp_|7iyE<S6z1G&;^b^1%jp#MVyAk`
VJSW{n!@gR#sym1~S0nA9?r$CG(6Rsk

literal 0
HcmV?d00001

diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1411d93d531c42f962d7fd0b7bdde14c2443f96c
GIT binary patch
literal 712
zcmb7Cy>1gh5Z;T=x$~ZF#l$8?0_h^NMGDx41`8r2h(wV@5eo&?Y3*B|PuzK}*>fUa
zbuW>Q7og-#LT7CSqN20p7huoWh(N^@vpX~2eDm$ks?os6*!9P6(dP<6-^*ZY)@HMM
zVm8-^AwbLmi|xP;t3ZX>V6!Sz*)Hrd2OQ>t%W6<#7%=m|i|R*>ygP~$(WjJNa-fk&
zX_Uw)5<v64zf*aOgp{O|y!UzLlh=K6mOuJ0`w<$Ux|YZxPsUPZ+6e^@FU35^BMI3g
z&cxG0?QA6E4{)#Nled_>#Ltg?a_Ub7q&$fyA24A!e}jAeg<%n)KbZUEe1q<pri<Ai
ziPczyeV@GA_P;AJw=1VyW&TNM=9b74oZr1Ya@}HPogdY;s|+ldL86^2F#stu?S<T=
zjP#Uex;Zsk0ws({o=MQHGFCx639>j9MzzrP`q1`F3DEA8D|ICy)UILS1FnSbl$Bu0
zBN430Hq4!M@K3tE<^2=<39ZUsp&!z*Oa<NCFCEHI{C?V@oQ&e=@pP`;XQ>Qli8zLi
zX)6DdIx}uru`KJWM+$d=?-$OZd02Rh){COKXdm35)^ZoQ`-Q!5_Kfom49aU4?y_6G
WXWyXCvhMy`?^L_?7u1G*!}t?VKGb&r

literal 0
HcmV?d00001

diff --git a/__pycache__/create_pages.cpython-311.pyc b/__pycache__/create_pages.cpython-311.pyc
new file mode 100755
index 0000000000000000000000000000000000000000..06aaa981519939fe14bd336620a4573f96c2328f
GIT binary patch
literal 3426
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
A4*&oF

literal 0
HcmV?d00001

diff --git a/__pycache__/create_pages.cpython-313.pyc b/__pycache__/create_pages.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8eb90549127ae6fa3d8ae5a505b7380b2a5a7d32
GIT binary patch
literal 2888
zcmb`JO-vg{6vt<Gy}R}r432@cQIl)~I5;Zaim#e{&|(9DCJ@QSEe&mvV=s;+yhgJo
zB<{uZ5}{NIsnjT^h~B7_15qzIMrnJu6AQZ=Dpl$!w<a7S<<vL3UfU3$O4_k@KA+#r
z&b;6JcdNc$K#+c$`aM3#A@mn%n29b|wz{D50}7!Kbq-;pq%Z|-`W*c!jcE~um_rCN
zAq(V|5DPgQr###<;$Xr<Y1UXIEvFMnIm(oMl7feaw6_$B_@9Q{NYm!bC}=VJs-*+g
z5vCxgyDcH6w`@xzg$dI^;&VspEw>d**b=nu7=&iX5=P*S?Phw*D-cnb3EFqD<n(#@
zZI%`n8a;)O!q%+1?)CpF+_b~&4K|v!YIzJz$ziIuygv%J`wGHbb&ca^5V9lKd;Mqb
zgNWkjee?n9D7%iqJI%rg9R*7=c7{2MW+{(#BEv}ws*I&q7H>S6(5S^sYiRiVa9~nA
zA&vwujEnOrHLZ%Dj}8ZiMPfNNB%Tp7&EkdN&~Q-nf1w*d=a8&MGjyw%p-&1Pn`TMP
z%ZkQDQ_5^2uJMcVC7ep7p<@B7DXj7GRXMtlmNj+}C!lC1u4m>Wae0PJI5V5V$w*og
z<|9}&x-@6CULN-F8fPp?vyxJYBxQ|`T{2p;i8&dQu-2%nnniyN5*DJ7v=h?hR8p2=
zawK*|z9vOeF<FYwrQ&hej3|~NQuXDi-uY`<W4WWUNPG}HHNm6ahAfLVIpMq6o6541
zt3Q0_v(?enlWUVXd)IoP!1*4GmhAO6`<MG~oXWaOwDr1o$(wWatzTKcoEr$`oRbAQ
zT%rZiz0$REdFA3AHRo(C&}~oc&TM2;Xe<iuyx`9EYzj?KeJr?F)9cnJLVvcW#MrM7
zEDfx*Z7>I)^Qi8?OB>?*i=1zR^Sx3@`29F|+V5r_xdnd@AFc2N16Fu+>b{4_cth$4
zCp)R5!_>aiF%ZdnQrAsa<N06w>_snI^-x2geyhQo)+8Xb!ey|+V%6Xn3bWG{GN%F|
zj)lPx-wD2q8p$h!vT)nDs{b}?;hOclJ((nEB~0eSa4Vzz&?Ke?ny&5ql9*L7Ir?XC
z(#RuVLIEb{kI8}Ph+uNfY0Wx%J0ZkmlW+scNW^2Zdmc{Xj2ZC(Xlho{r~=0uly~7~
z7*xs94d`$SF*a$c%!ZFZH+j^%kiACJ$f|FxCujd~y|uvgJ?Pk*Cg;Zm`jb+f<L21%
z*o|}9<0aa5U0RZI2aXr$j!j!b(bk@~wP)KlZ7!%jwzaRu?hURjK8W1E_Rx9%o4gcw
zIGC44p4iT2+e{*x3UtfM2E>0<<oY(azA{yQhu_CM@(BTskCI(AQ$@?}y)jkYbci-@
zZ%{ExLJA#5Z^hI$1p{4zRVkLKw$6Ge>2Wx8q8EGdxIaA(w2f5;ybl}RL#$2*YjW~G
zC}9jJswyG1D`&Mzc=kUiAvci`q=XWauM!<Ja642ci6Arq+F}Tz4pc_kP8o@1byrOk
z&yS6dO^Wzkh>`u^bLuW;63PtuLYhk`vesnQYBjM2N1a68Ah5n-OEA<}1AB7+8PqyS
zO~;YMsDYzs@YqmRH`4=d0}Jxup#BWm4jeD$>>X<WqIbQsB-CZwccZbhKufxKl^E;N
z$!~j~GayZWn#$+@wXYbM&IhJ*{x5URuL|_nhONW361g>W$9ZdHIhpn8y4Ri;+IQEz
z#v;>_XIfU$8_avpZAAHiQK`szH#o1s=w1Jj0L%Qs3IP}I;f(uEzsX2M>H4i-JNnE1
zgtnj)8QWn!olM0R=Hvl<9Qp{|>QTu4W+;l<5)tKiikyF-!!ImW>YW!&R_fqZQyp~}
HyTRrkcT*`j

literal 0
HcmV?d00001

diff --git a/__pycache__/newpost.cpython-311.pyc b/__pycache__/newpost.cpython-311.pyc
new file mode 100755
index 0000000000000000000000000000000000000000..64255b78569aa8e5067d78088d7271ee97c659b8
GIT binary patch
literal 1704
zcmah}-D}%c6u(!W{*Y6zTbr6JMs4P}ZcV*WcWfoBY?Vhn5{Eiow;I;rNVl#tTlOTm
zNsJ6?2{b8&J~l80eo7g6*<Uj3VVDsF3S$p@^T?j^w0mXQjT6d_ug*Q^chASwImdbx
z2>1Y|_2}#3Z#)2h5@ke`D;$1;g_l493M_*>#5+}{Dpa0=LyXST&KZ+uoSn_H3cUsL
zoB~%sjQN{{$;6=TQ3?h!N);qCZe+3r@I&M0@ME0sB`_cXhorzgtnH7HCSwpwm)1u2
z1A7?RAHkr>nr!=+-S`0CTcP)`*Z$bE$r|1_=O#Ou4+099^cp*|n9S4WM)>hvVJ2fV
zX%n<@Wlz&&v?gbAZO>^d02J1QKLLd^8O(W;bvQldo}c}b86kLUB=2cU34G^k@+PnN
zLgVC3Ps@*QeXKI$qZ74;z&Q8jY|THCO=wak*u!1eA9vz}tuVIr{I4yU5r=ThiHRT+
zh-b{7Y4Ev{QARh#BN%Nk^K;ifZA?X!NF{PVAGs4*imc=ssdQ!~mCcFiOm11MRdqub
zFV}UXrKPxN5a+lkS5*V4MqI4bS0y~GaS<scgGe#)-sg*7r&caE=(vb8L<y&&vBrlh
zsm0XooOnh2GP}Iw#$C=zsjT?LeMe18qJ(r=Tud*ebK*xD8NS$*&6d<!-LP4?T#|pV
z8Is86HB>7XWMs27t)v<@tyb4<k8WrW$=}B2<hrI;HJe8pNUj?Ms8%Z2Pmnc)FZq3~
zP(->NbT#sF4m3u{TMv;lt__J>E~zNywJBxQ=7t5aJ!Dr46{L~&*{o9^n|JG@k$%{4
z!{$i9w4{?s5l3_sNj$1nP(nck<uTe!$W;X;isfpth_r-?)``!x+NRCBvi3gqp2d%z
z!@ae@fp=<qv+E7@ydmq{fj`)~xwFt(u%`R|voCHvzqNb4&2|0Jo<C|$A3)Ape-hpb
zTj9QNVf#*NaVOKt{2|Q!F3fd4NOpxAJ>iCR;k8eA5qlonx!SsFo$o{bS@>yq0Khx<
zsLr<!hJvfgk0w;Leq6<}2_@<T^c9so3E{y106=|1{p)b-fMqvtCwRLHr5=<zQ0n`F
z0|2QZv+nl&!uH)((wevC`;dMXdK!8%vo&MQ`~?F&7~Xx{-uU%w7bbf!*@4M}w}P{~
zt6g}p2QPL;>kt<g#CZEmWmEsLd<}O|MY4ehiFE*{#~S%YX+g}$RH+Y3MW-*n0FAUp
zo5AeJvrwrj^)mWQyM$HpS=Jw5HlQJdgDU_|cfk4K>Vw(N<mv;#a()92!1p@f-Qntk
RfaUxKOb}igfYZ#${~s!af(`%x

literal 0
HcmV?d00001

diff --git a/__pycache__/newpost.cpython-313.pyc b/__pycache__/newpost.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e1fec252b26ebf57fd988e0f5b2c199ca903eed4
GIT binary patch
literal 1507
zcmZux&2Jh<6rb5;cfo*-9XF1X+M41LLW)8wn@Y8!Mopm#3C7AU8#}dB3zi8%g@w*8
z{-8aODpKP3;8P?YbM38vNwtYn#TvVkrS{TWD*6X>W?^mD$&+?|@B6)ZGqb&LcnC0B
zj~`WkQvmpr3myprruR8xo&ybN@D3o5p>RjIEf4|qbs`a6n~(Thl!&B>7Xgv0FyZ@~
zCn+Q#^;b$ZwrdS+_y&17gxM#uuP3u=&%p}hN=_O~4|vnJ;&lSl)3JR=5C!Q0XG*%H
zvR#}dP0+;jAcrZf1U$Pgc{LEwMb({zXY1ohZk2a>hBTiSZ;ColN6wg;c-)z+%j)R6
zc1_aZFwkV($5us`+*LeY{j))@0_*Vo83Lz0&VgHg08B+!v>}O=GyMx}S3$s{fqL%U
z`d)tstc-hB^}NTOU=%Em=^)KdiqZePFZ6Y%*C<%>FQfN*Up(#C=cBB*lRZ>HB3S4s
z#hP8m^N7ND$9H*V_KVJNtP*R)?tdG*6<dgD#ZER?(6VX~<qE|`)M{F`g|4(MOmdkd
zvUzY48BNp1rkzBsb~(c?UlQR;&E{MJ-TNx9XSFLGF^O1(IA4W$qVuVi&1b(ZqO0f|
zb#Y;kcTvq`Rdn;dE9NpNgDnH)a|^j5`i$^vl^CW{&1|)8DjD^f@jdnNLR2BRRWBKs
zN-a_|Z7Q10b?Ucl@_;`BDjRKLH3?Pl1~%F@S2P<978f!IW=*cPN>yyp$Ux$ob5+M0
zzU#hbWZ=W|)@vqC1gKCcQ@KA7>gQ;d8kq0{q>?)ysto2s_|2wpgUUQ%E@SccfjpwI
z)Wc>2rz*HqS;LztqglbJYQ0&lVv;iPI*+;5+N8>WCm*utDfU?cd%s<97#M!Kxfhu1
zesCC!?94x#-@e|R*bk2F+}OIYJNrW33&y(>hfwaWKc3zXjql{2<+lrOLNhNzGtS3z
zd!cmq!qHG@C$W{-{-k?;A1Y6#A5A-BOV09l&eE#0T6T<wPPyjP8jjg^8f(s4=Pdv~
z!HmG*N0{Z16>=PI3o3`4pmERyox|uo;a>oRCE+;r&DSt<Fcj(D-4BMI-rbt}`SL#^
z2#y{>@yX<)$;X%eg5fuC`W2ksUHf(HHJm#<kzZ_h^3*FhwOjrje$->5011VTG&Zdt
z>etxJO>Efg*d<rto(SRpED~W0zXRrjTGgH6FM#ktl1tp+zust8+I9RTi87J@8ZB;o
eD?$i+R{@;(156!&P)`PM`~ZY|z6gxE;r{`Ua6{$*

literal 0
HcmV?d00001

diff --git a/__pycache__/parse_post.cpython-311.pyc b/__pycache__/parse_post.cpython-311.pyc
new file mode 100755
index 0000000000000000000000000000000000000000..6e46a0c7e42debab697851e72252658e8c085159
GIT binary patch
literal 1584
zcmd5+%}X0W6rahian!`tVx_VaQgESx)~y#&kU}v+4=RONt$`{_W)c&#?lQX;3@PN$
zQ!njJp$gK2McRS~5B?e1vQpVop{MjDc=OaZ8xs@6l0pxCJNv$7-tWDAyKg^5qumJT
z*~jB74<YnZ7<B?WptBf=O+*pJ1(XspRKNyKVT`Es2Bkt2CsACkio>&U>=UXx%*h!n
zEeY2Jb%7N2*)PD|L?yI)vC%3hcItUyBj3>XK>OUVUSA&{Dq$)OHbC2slby~+5X#GS
z-RY@o2mx|O6EcR1;I0u3w`ST6*LRv_%d<7|?X@7a;{4%BJKL(5{6`gcK?l2=>S_0#
z_O$ek)I0hC(Fh<$FA>4hyCb*V!5i1&-YkXw605Hix|$c};?`_2q$c5>tBTJTltfj0
zUBzCNs)o9lQlF|bYH|)Xrm7va6O&ajDd3qdhBeEy9Zd`;D$2uIBM0v1;9j>G*Fc|*
zcln*1Sp_}K{BYV_%jB|tuLxSUnZ>y7n4AkZpV$t!#9aCkXn~mt%pNhY%Ndg!x&!VU
z80)+cmwZ{k_+ie{CZ|3TDc5v^*#a&Wi=AuQifJ&7GM&C+8(P|=Ov@I`Y?kqd)`qiU
zu4$IeZMH0MhOG_1@6x=;$8Q6c=!bnDrl5>YNaS7QZRGvj&Zwt6a><BCM#}vS@7Cz<
zz3p+As2)+9+&g2Q^5ARoVBiQJ4(=~~S*lD-yUL8G%zRhozbW&_3opHeoU7zLCGV0|
zkF5Ty;Oh#?Y?~D&0qbD?=*i(?O$Y9hDUVDwXAe$JR+Pzu7r<)EB?*rtnoezvxn#&A
zL*@P-BvMw+pkXL3aq;sGUT)CFeZ&WZqaWBgnJ`ScUSN;;9Wcdz${q)HDq)OIP_!Ie
TC+Kdab)CxHIC_e%vH<!wLccmb

literal 0
HcmV?d00001

diff --git a/__pycache__/parse_post.cpython-313.pyc b/__pycache__/parse_post.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b7b14da82ca8719a37993944ad869653f795cf1f
GIT binary patch
literal 1429
zcmcgs-)qxQ6uvjfx@>FeCUdA^Qe^=PW0}atgdxZ_ko`iMc5@CLp}CFKW+^wBus-$G
zCw&=gFi?C_^r3s}pV1km5)lNS`X=-r@Z8XtJUBK%ypWvleD~b%oSfWyJCf9oVBCB2
z*`ypoKbR8^@PpC00%i|sNW)8rGRrODMNDxTY5ZkGITL4uHVa+NU|%$Jm$)U16nI8;
zM;}<`cMd^y59Lu7hf|T&@Mf43Wrc_j(NuSK`=s?;9&3CLgr6EIY$ih0tQexmUPGG$
zp$D2hfo8X2EfK0`r7$M4u`ftPY>1}18ll38U()+m^@;zzzCP$m|Cu^H5bMZb*oVlb
zkd_23iD>~&-4ssk&AC$*2lLz+wTALsJl`0~oL{YSiUv=v&9)nW`8L~&)s$i=ma_3c
zxvQ)wS`H=_+N^2-b8WV_0W4P&YQ=V3l^rHj6(&rp1auzg9fwdA@M@;d@1>+t)(gZ>
z6zuI{$@Eif(UwChgzBzMDU<U>$E6i^l6)Re;1&aSfE}@|qD?K`1-b;z4lQSRUtltR
zf|7zw4PRs_w{?p+OfH>H``6XSwnbEf=*Ba$s}^j7sAkzVO(?CRQ-^FZfr-klKNPv$
zMDzlPutqo%Y~mXFA|_uXpC@1D4yRl4<gq;Ii8pG)zuEoi*H;g2d7={I4rf~O_(ysC
zgH|7D;G;|LA2nx}J$a=iuN}*4pVl9?)=S6hB~O0hiBJE*x<A%Xd}SZl&C!Xs#rj&~
z&e2AFso^%|c~4x3XN*PNuP-)?rab3~^RbBi8BZLm4SyGtHMs*_K^dO1t2Fp^L9gB+
pI>Lxyc=_V2Wg9zXa+_WRm)!ymI}AU0jPX|_eM6%ip&v`ZieKi12ZaCt

literal 0
HcmV?d00001

diff --git a/__pycache__/rebuild.cpython-311.pyc b/__pycache__/rebuild.cpython-311.pyc
new file mode 100755
index 0000000000000000000000000000000000000000..467e88eb78047521eef0557a53722aab95d005a6
GIT binary patch
literal 926
zcmZ`%L2DCH5T1ESlM<RXSP%q_Yo&p0!993sK|HASq!q0P35X<l&ut{>hPR2dvV|am
zC;^Z4m_vz?{1C4j$RRFx^3+=(x1OB$%r0@Ivu|hToB7_i^Je#3Hk$#mA1{8|+X(Pm
zfza42m|mse1UPW4LGkYsi^$mrC^C+FU?$EKb+<wak)<d~&^_Iv><M_#jY{)DkH8>G
z9HWQbd6lTbu}AqqR73Fa0leHgX3d3&1aH(EwRw!QD<J?vi8%y4;te7$!ao|xaGMA5
zcXqZf>@OMT>i(|9`ipvv^#?tg_8^=%AawE^XtE2t?^gGA9_`$JZfqD2pFMeOv|J%w
zshDSK81Zt$ahtB03R0DpbR8L_#i6LQnj%=LNKtBvSB;V_+#okYN=>JNm06})t&3Xq
zKtvR!s3~S5V7x5V5du7P)%Xm<IA6E+ow~5NDDk)A$f`J8Sa!{^Z6Pfw%B^aR-)bBM
z=~*n7X`kBb_Q|zjoLTx}el|aCb~f9W$C&<@f1mer>q9Jzu;621oXJgqv76eppZ;RY
zBX+%u-5aOLZmEx_ynk=VtP!((X6a)7s~obm5nJ>1x=0e)#stX4B+El)j+p7|HA#f5
zDfLSKIgQmhcwMz+nxH<(caSS8&XPM{yi<30t0wNsO9a*Dac`3&8N@MU+xi;AsvoWi
MTSRK(f2T$N0Qtnhl>h($

literal 0
HcmV?d00001

diff --git a/__pycache__/rebuild.cpython-313.pyc b/__pycache__/rebuild.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..028a3b895e5a68ece5cca941736de6ab5794e761
GIT binary patch
literal 826
zcmah_&ubGw6n-<CY(m<!u>lVSld({7E4Zgn3gSVj2%3sn1A+%hcBg9~$%dJ%G@jx~
z#Dk}T$MjbJ60cH9trKsadaLd~;G6BXjf>!eo%iee-h2B+#bN=_zC8c#ZxDc=IypC*
z1ko}EyWoIB9)URXL=cBAgP=aKj1vvqa*=;wCPoH+(M_!GLK7OZ-2_%ke4jK)L!(pX
zkXpiG&?IGexDL>#FEZz_hTf906=+h2X0eLih&|Mj*$ig5`4kaT<ih2~`Ub!p=*|DU
zEpv&CZ@ZSdE!Oq#9W%E<Em4<2y?VCC2P?bvrtEA!-n{>et+5A<Cv_G|E~L=d6D>u$
zJqYAbTBb7HP{=^29N*z?IOJ;H6}&a%F9$83OI1oTJuNP&#iTOq^mw<^=NAw?F@{)%
zqF!5Q1r^zmT0+K{TD4yVJ#Krv<-O)3+YLN!``y6zxv&Lqhn=o>doWVDBo+(E(_A^i
zXAH-M`H$9n>%*<_)nk%-S9x3cT3S6MH>QQs_~{S2@QqdvXmvs+*Y`4$);`(u_U|21
zJML5tXyubQqAS0$Fn8tD1e*WPfc6o!ej5mma5>-~nQqYE?)V~yX?)se5Q{o4;-m6+
gdVv>q`CYMusn%PT@HsUIAyX($p&ZdXS&JEe01Dfl<p2Nx

literal 0
HcmV?d00001

diff --git a/create_pages.py b/create_pages.py
new file mode 100755
index 0000000..7885c9e
--- /dev/null
+++ b/create_pages.py
@@ -0,0 +1,52 @@
+# File tree:
+#
+# / -- index.gmi
+#   |
+#   |- post/ -- 1.gmi
+#   |        |
+#   |        |- 2.gmi
+#   |        |
+#   |        |- 3.gmi
+#   |
+#   |- user/ -- deadvey.gmi
+#            |
+#            |- max.gmi
+#
+
+import config
+import parse_post
+from datetime import datetime
+
+def create_user_page(userID, username, db):
+	with open(f"{config.webroot}/user/{username}.gmi", "w") as userfile:
+		cursor = db.cursor()
+		cursor.execute(f"SELECT * FROM posts WHERE userID = {userID} ORDER BY postID Desc")
+		userfile.write(f"# {username}:\n")
+		for x in cursor:
+			post = config.user_page_post_format
+			post = parse_post.parse_post_format(post, x, username)
+			userfile.write(post)
+
+def create_post_page(postID, db):
+	with open(f"{config.webroot}/post/{postID}.gmi", "w") as postfile:
+		cursor = db.cursor()
+		cursor.execute(f"SELECT * FROM posts WHERE postID = {postID}")
+		cursor2 = db.cursor()
+		cursor2.execute('SELECT * FROM users')
+		post = config.post_page_post_format
+		post = parse_post.parse_post_format(post, x, cursor2[cursor[0]-1][1])
+		postfile.write(post)
+
+def create_timeline(db):
+	with open(f"{config.webroot}/index.gmi", "w") as timeline_file:
+		users = []
+		cursor = db.cursor()
+		cursor.execute(f"SELECT userName FROM users")
+		for x in cursor:
+			users += x
+		cursor.execute(f"SELECT * FROM posts ORDER BY postID Desc LIMIT {config.posts_in_timeline}")
+		for x in cursor:
+			username = users[x[1]-1]
+			post = config.timeline_post_format
+			post = parse_post.parse_post_format(post, x, username)
+			timeline_file.write(post)
diff --git a/example.config.py b/example.config.py
new file mode 100755
index 0000000..7a1481f
--- /dev/null
+++ b/example.config.py
@@ -0,0 +1,44 @@
+### General ###
+site_url = "gemini://example.com"
+webroot = "/path/to/root"
+date_format = "%d/%m/%Y at %H:%M" # The date that is displayed on the page
+post_seperator = "---------------------------------------------"
+posts_in_timeline = 100
+
+### SQL settings ###
+host = "localhost"
+user = "root"
+password = "password"
+database = "glogger"
+
+### Format ###
+# The syntax for this is pretty simple
+# %S - post seperator as defined by post_seperator
+# %T - Title
+# %D - Published date in the format specified by date_format
+# %E - Edited date in the format specified by date_format
+# %C - Post content
+# %L - URL Permanent link to the post
+# %U - URL the the user (poster)
+# %N - the username of the user (poster)
+user_page_post_format = '''
+## %T
+%C
+=> %L permalink
+%S
+'''
+post_page_post_format = '''
+# Posted by %N
+## %T
+### Published: %D
+%C
+=> %U %N
+Published: %D
+Last Edited: %E
+'''
+timeline_post_format = '''
+## %T
+%C
+=> %U %N
+%S
+'''
diff --git a/glogger.py b/glogger.py
new file mode 100755
index 0000000..cfc997c
--- /dev/null
+++ b/glogger.py
@@ -0,0 +1,38 @@
+import mysql.connector
+import config
+import newpost
+import rebuild
+from datetime import datetime
+
+db = mysql.connector.connect(
+	host=config.host,
+	user=config.user,
+	password=config.password,
+	database=config.database
+)
+
+cursor = db.cursor()
+cursor.execute("SELECT * FROM users")
+
+
+username = input("Username: ").lower()
+
+# Check if this user exists
+user_present = False
+for x in cursor:
+	if x[1] == username:
+		user_present = True
+		userID = x[0]
+if user_present == True:
+	print('''What do you want to do?
+	1. Create (N)ew post
+	2. (R)ebuild''')
+
+	answer = input()
+	if answer == 'N' or answer == '1':
+		newpost.newpost(db, userID, username, datetime)
+	if answer == 'R' or answer == '2':
+		rebuild.rebuild(db)
+else:
+	print('Sorry, that account does not exist, If it should, please ask the webadmin to add this account')
+db.commit()
diff --git a/newpost.py b/newpost.py
new file mode 100755
index 0000000..2076a3b
--- /dev/null
+++ b/newpost.py
@@ -0,0 +1,47 @@
+# users:
+# +----------+--------------+------+-----+---------+----------------+
+# | Field    | Type         | Null | Key | Default | Extra          |
+# +----------+--------------+------+-----+---------+----------------+
+# | userID   | int(11)      | NO   | PRI | NULL    | auto_increment |
+# | userName | varchar(255) | NO   |     | NULL    |                |
+# +----------+--------------+------+-----+---------+----------------+
+#
+# posts:
+# +----------+--------------+------+-----+---------+----------------+
+# | Field    | Type         | Null | Key | Default | Extra          |
+# +----------+--------------+------+-----+---------+----------------+
+# | postID   | int(11)      | NO   | PRI | NULL    | auto_increment |
+# | userID   | int(11)      | YES  | MUL | NULL    |                |
+# | title    | varchar(255) | YES  |     | NULL    |                |
+# | content  | text         | YES  |     | NULL    |                |
+# | pubDate  | varchar(255) | YES  |     | NULL    |                |
+# | editDate | varchar(255) | YES  |     | NULL    |                |
+# +----------+--------------+------+-----+---------+----------------+
+
+import mysql.connector
+from datetime import datetime
+import click # Used to write post content, it launches a text editor to type into
+
+# Other python files #
+import create_pages
+import config
+
+def newpost(db, userID, username, datetime):
+	title = input("Title: ")
+	content = click.edit()
+	content = content.replace("'", "&#39")
+	print(content)
+	datetime = datetime.now().strftime("%d%m%YZ%H%M%ST")
+
+	cursor = db.cursor()
+	cursor.execute(f"INSERT INTO posts (userID, title, content, pubDate, editDate) VALUES({userID}, '{title}', '{content}', '{datetime}', '{datetime}')")
+	cursor.execute(f"SELECT * FROM posts ORDER BY postID Desc LIMIT 1")
+	for x in cursor:
+		postID = x[0]
+	db.commit()
+	## Write to user page ##
+	create_pages.create_user_page(userID, username, db)
+	create_pages.create_post_page(postID, username, db)
+	create_pages.create_timeline(db)
+
+
diff --git a/parse_post.py b/parse_post.py
new file mode 100755
index 0000000..166bfb5
--- /dev/null
+++ b/parse_post.py
@@ -0,0 +1,15 @@
+import config
+from datetime import datetime
+
+def parse_post_format(post, record, username):
+	post = post.replace("%S", config.post_seperator)
+	post = post.replace("%T", record[2])
+	post = post.replace("%D", datetime.strptime(str(record[4]),"%d%m%YZ%H%M%ST").strftime(config.date_format))
+	post = post.replace("%E", datetime.strptime(str(record[5]),"%d%m%YZ%H%M%ST").strftime(config.date_format))
+	post = post.replace("%C", record[3])
+	post = post.replace("%L", f"{config.site_url}/post/{record[0]}.gmi")
+	post = post.replace("%U", f"{config.site_url}/user/{username}.gmi")
+	post = post.replace("%N", username)
+
+	return post
+	
diff --git a/rebuild.py b/rebuild.py
new file mode 100755
index 0000000..cef252b
--- /dev/null
+++ b/rebuild.py
@@ -0,0 +1,11 @@
+import config
+import create_pages
+def rebuild(db):
+	cursor = db.cursor()
+	cursor.execute('SELECT * FROM users')
+	for x in cursor:
+		create_pages.create_user_page(x[0], x[1], db)
+		create_pages.create_timeline(db)
+	cursor.execute('SELECT * FROM posts')
+	for x in cursor:
+		create_pages.create_post_page(x[0], db)