From 55cf1d377cb73c2c08881a1d752d7c2f27cf5ad1 Mon Sep 17 00:00:00 2001 From: justine Date: Thu, 17 Mar 2022 17:40:32 +0100 Subject: [PATCH] Dockerized --- src/Dockerfile => Dockerfile | 6 +- docker-compose.yml | 20 +++++ src/__pycache__/app.cpython-39.pyc | Bin 0 -> 1692 bytes src/__pycache__/classes.cpython-39.pyc | Bin 0 -> 1961 bytes src/__pycache__/funcs.cpython-39.pyc | Bin 0 -> 2240 bytes src/app.py | 111 +------------------------ src/classes.py | 49 +++++++++++ src/funcs.py | 78 +++++++++++++++++ src/notes.pickle | Bin 406 -> 0 bytes 9 files changed, 153 insertions(+), 111 deletions(-) rename src/Dockerfile => Dockerfile (74%) create mode 100644 docker-compose.yml create mode 100644 src/__pycache__/app.cpython-39.pyc create mode 100644 src/__pycache__/classes.cpython-39.pyc create mode 100644 src/__pycache__/funcs.cpython-39.pyc create mode 100644 src/classes.py create mode 100644 src/funcs.py delete mode 100644 src/notes.pickle diff --git a/src/Dockerfile b/Dockerfile similarity index 74% rename from src/Dockerfile rename to Dockerfile index e784cff..4f211c7 100644 --- a/src/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ FROM python:3-slim-bullseye WORKDIR /app -COPY requirements.txt /app/requirements.txt +COPY ./src/requirements.txt /app/requirements.txt RUN pip install --no-cache-dir --upgrade pip RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt -VOLUME ["/app/notes.pickle"] -COPY . /app +VOLUME ["/app/data"] +COPY ./src /app EXPOSE 8080 ENV FLASK_APP=app CMD [ "python", "-m" , "flask", "run", "--host=0.0.0.0", "--port=8080" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0fb2252 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3' +networks: + traefik_traefik: + external: true + +services: + sqnotes: + build: . + image: sqnotes + volumes: + - ./data:/app/data + restart: always + #ports: + #- 8080:8080 + labels: + - "traefik.http.routers.gitea.rule=Host(`notes.sq.lan`)" + - "traefik.http.services.gitea.loadbalancer.server.port=8080" + - "traefik.docker.network=traefik_traefik" + networks: + traefik_traefik: diff --git a/src/__pycache__/app.cpython-39.pyc b/src/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ebcb052c74652d059ea502410ad4c335a3f2da38 GIT binary patch literal 1692 zcmaKs&1)Pt6u>3T_w1+b#7Uacn&48l2d|;fQz(Iw77BF>4w$NkWwMg@!=ssvMnmFd z-OKiB=%3&~FZmyO=%xRJu08c%@Tu=<)=v6CXV9A`y{9*NKRqeybW#FO|A$YX{~i+Z z2X@|leCRxZR{aJ-5J7XID5r{XrabN`pZhA{feLv@(a!Qn#XNSpmnSOascP|-YV)@0 z@Q&*8uIllg>hnG&lFF?$<=e8qCeYiS?+9N66Dq<>CL$64M8JB-jVB@y>4Z5;OSGNk z?q){1nb8qlH@+*kMDL90U%`G)^u^XCh4pM7lfllPkOdipHuy5nsx#ZuvJg^_j8uy} zGt!3NWcsXL*htG4wXBSdwG=Zg$Hqpr&PS)E9#HESrICZkCZbjg)GHfLq}gcWY@rSSHNivIi8SW-zO$Ge?rLx^q1`u@;&Uz1^tm0Y4bfKhh+K5CIW*9Y{dkr zsh*qAL;`!>C0o-Ia{M;l&;K9K#KJd;N!PFr5nM7L9Uj>b(wC6E4_O+>F2#h4T0NKg zx-%`6Tx1h@Ff}TFLoF-xprr#y&-$63RMrEax{ZBrRv4Q+eKnQ~Gb;-XWlD5}0@3Ie z3IsIpcx=kePpRagDe=#5i2eYq*AIufEX}ZbQO`!Wl4@A#@i1E~4i@J&Yzm> zFFYVmO<=+m?A#i5!9+JYCCGC{S8Sd@OM$5Gh-wNE^%jb|AeITP!T}t3ZiI)0nVDSj zpfK{48MLf#W=b|#!=||O1DyXJiVlj0D3G(GX#*Dk=HYx#KSBfkjECwRsX3O7_z-P( zK#`YZ$+-iYbdD;EO8HBKqCB0 z|H3!H%HI@xo5IyWq09?*NK7aK02#YNgi8dlMMn)bT%`U8#K7n2SW7tV$c9I%6b{m@ zgWg5gd+3@p0GhIdv#%OlF*zFYkQE`ejL+~b!ocOr)dJ;UQGW2$whlF literal 0 HcmV?d00001 diff --git a/src/__pycache__/classes.cpython-39.pyc b/src/__pycache__/classes.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..168291d68b8c97df460486f5a14b16532515dc52 GIT binary patch literal 1961 zcmaJ>y>Ht_6u%=WiK66uIY2YC=z*vP0kIi0KnFt>45Wd(*hAB$%0SS(lSP{!%JJmX z1U4RDhGq!&w?+$22Qc$75J4uClZhcr_$*;@`qttGH?OTp zOPJhxOL>d8;ne0GZeNp0hj+OHtId00yLeN0o0f`HEGkQh z?^K9>R|EG3%x5t3kAaj%NqkaLptLlB8l?r)O)p{F*w9h2Amt1LV}TSbSF&Lr4=stXN{moiNHE@EtFm$tPwQ(f z(C~gCvI8RTKlNmmDKCGuh=h{jhuGFf}C;gC5d+lV`nzoOOi(IH}rp8+#hgnka&Y{cLrbW4UYB( zFNS7i^VREbO=XtgQ)q*g4bV>U2&h5=6N!H=`#`F0Bc;)+31U(?Qb&mVhj6ZevTWL? z4lV9#pw<#01(DT2Xzs(*&=jy)LPKFSW11LO1|{4ojT^|aGwU7wk?-$qcq=O-rgw=8|*e9*Xap3&r}k# zX(rhe^5gt5TjZFp`mlQx$n(X#(Uv{VQLDuYD1oC7OgoFtK2 z333q&C0uq9#0%6ra#tY$r`B`FUuvO|SD(k_=zk0fj>cE!UN+|Ner4}D>>F$A|M&36 zHp2cF9*Jr+Bmi^!l+bQnp(%VqKReM;6ICbq|twVhfr~?X_tK)`6w*c&w8`a+NeP|NC{{*gc z-REf0*PfP)V?@RGF)w|;a(o|J`Xa`C-}hfFf_TX>qf}KU*pglJpaJ>_caIu}w_QsN k7iD#avFStSPS@Vnw-_^WH^9@nxYI)X9k{tlD;19bD@#{d8T literal 0 HcmV?d00001 diff --git a/src/__pycache__/funcs.cpython-39.pyc b/src/__pycache__/funcs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d66397d728d7b5be75757187a8ef396c44b64fd7 GIT binary patch literal 2240 zcmZ`)&u<$=6rPz~ukDTFqzM!iTC{LL*$UaTAh<*kkSIOj1BpP5K(O(Q8^`;@nc1`? zTAz|D;ve9U9{Vq?#EBDUE~qEIH|sc#lB~7kd2eQC-uJz4-b9OwKEw0hPoMAqR;S2U7I9y*JJOSN{JW|q8-H@yl>WK9=c&3}fYp+V zuo|%1u$JU9tfu1f9;_9)3d@)8?6C0Nf3ORC!%H{Ka@8l}@)79JyNTC)ibirND3}RD zFkCvZNSp}*E0}c8xLGSW{bQ_#g}u`+{Q%FVR#C2k>{tgf%A-IIwd&`YJ_&|{KxWDW z*f>zX4Ncy$A83xP5RhkmCgf!;8R4r_uhXR!dZAm^Gt(JI`GKxsZYeUO!6XZXwQc_m z(@nVEKI-Z$%e&_2c=!t;G+m?n-NA9%#|kH9GZ~Q=%hO7xfrhy)-VzP27trrhFqaQy zhGtkozD1`ZWWsZh0qEk7hZ9lo3sJB_ycV4Oh@831WoHg&>GBh1zW5B((eF7?Skbg) zQ9o0;<;cbu#9$+cQW==&r3&%`l?0Iq#>4(7hM5s%3h`U}inQL_)rz9-{CFu|?eB(8 z=~dH9Hyf+8bmeg}hPP&?>Ne1nPBI=?)~beNS~h8(owEdUN>GEh_+z10;kl+57mgW0 zdoXS)X2L7A=Q z8(M-i)PRPFCRgbD@Ic26nnbC+p(={Vs_H{@Bqx%#*w4#EOd&4VYxWhJ@S{e-0bHCu zu~;^sS#bkpDaxhFGk|;2_uFh0R+b;~_$c(f~rP86J-@{gAZ7@uuSUc$7 zK!w#Usx=Hw6Yuf{ZwvhaJXo-q4-;kbC>h@kXaiGoc82f^4oIDe$N}k4oZ-+E?2M0u z_Hkq!%06egTX3o%R9|-3kuL=RJEwaV@Ro`duu@C_Xiv-ZMA&2xG9A1+81@fr{`%)!?~Osdj<8(Vd$Vv6i3 zW=$pFfvgqoqeU?Z;19W`{N5mo*4xBuK0z}_)_vq(9D*iGk`SQ9l2WN))5gC&M3so{ zBxR0&n92Mhfq4j17oI5=ctwR1pNy=lUafpa?HHq48@7=?bCZ zY7utOxkPvYWH#wgITea?9DV8jjw>a1Dj7^G?VlEk4Y;v1)7J&uxn8Et%r!GH0x(+82XY;@M+ ztRKZ@1D$HlZYWA;q)y7ZRuGU;xU(vedC?fvSC*bZkV;nC68dA>@wU=ZpYHJt6K0J2 zkd=N6PcK|3>wTPRqfB*%>CUo?R@=E$ZR~N?k7y*IhH_;;pTlS?nl1Q^bm-FE;0 literal 0 HcmV?d00001 diff --git a/src/app.py b/src/app.py index 6c48820..b23151f 100755 --- a/src/app.py +++ b/src/app.py @@ -1,122 +1,17 @@ #!/usr/bin/env python3 #coding: utf-8 from flask import Flask, render_template, Markup, request, redirect, url_for -import markdown +from classes import note +from funcs import dumpnotes, getnotes, catnotes, delnote, findnote, addnote, mknotedir #!---------- squiNotes.py ---------- # My notes-taking app #-----------------------------! -#CLASS -class note: - def __init__(self, createtime: int, modtime: int, title: str, text: str): - """ - createtime, modtime : epoch time of note writing / modfying - title and text are str - """ - self.modtime = modtime - self.createtime = createtime - self.title = title - self.text = text - def rendertime(self, pretimestamp: int): - """ - Render the given timestamp as dd/mm/yyyy-hh:mm - """ - import datetime - timestamp = datetime.datetime.fromtimestamp(pretimestamp) - timestamp = timestamp.strftime("%d/%m/%Y-%H:%M:%S") - return timestamp - - def flaskrender(self): - """ - Render the note as html for flask, using flask.Markup - """ - rendered = f""" -
-
{Markup.escape(self.title)}
-
- | -
-
Created : {self.rendertime(self.createtime)} -
Modified : {self.rendertime(self.modtime)}

-
{markdown.markdown(self.text, extensions=['fenced_code', 'codehilite', 'nl2br', 'smarty'])}

- """ - return Markup(rendered) - - def __str__(self): - return self.title - -#FUNC -def dumpnotes(notes): - """ - Get our notes list and save them as pickle to notes.pickle - """ - import pickle - with open('notes.pickle', 'wb') as mpf: - pickle.dump(notes, mpf) - - return True - -def getnotes(): - """ - Get our notes from the file notes.pickle - """ - from os.path import exists - import pickle - - if exists("./notes.pickle"): - with open('notes.pickle', 'rb') as mpf: - notes = pickle.load(mpf) - else: - notes = [] - - return notes - -def catnotes(notelist: list): - """ - Concatenate a list of notes into a str. - """ - final = "" - for note in notelist: - final += note.flaskrender() - - return final - -def delnote(timestamp: int): - """ - Delete note in our pickle file for which the createtime corresponds to timestamp - """ - notes = getnotes() - for note in notes: - if int(note.createtime) == int(timestamp): - notes.remove(note) - dumpnotes(notes) - return True - return False - -def findnote(createtime: int): - """ - Find a note in our pickle file of notes by its createtime - """ - notes = getnotes() - for note in notes: - if note.createtime == createtime: - return note - -def addnote(mynote: note): - """ - Add a note to our notes pickle file (and sort it). - """ - notes = getnotes() - notes.append(mynote) - notes = sorted(notes, key=lambda note: note.modtime, reverse=True) - dumpnotes(notes) - - - #----------! MAIN app = Flask(__name__) +mknotedir() @app.route('/', methods=['GET']) def render(): diff --git a/src/classes.py b/src/classes.py new file mode 100644 index 0000000..dd7e7ab --- /dev/null +++ b/src/classes.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +#coding: utf-8 + +#!---------- squiNotes.py ---------- +# My notes-taking app +#-----------------------------! + +#CLASS +class note: + def __init__(self, createtime: int, modtime: int, title: str, text: str): + """ + createtime, modtime : epoch time of note writing / modfying + title and text are str + """ + self.modtime = modtime + self.createtime = createtime + self.title = title + self.text = text + + def rendertime(self, pretimestamp: int): + """ + Render the given timestamp as dd/mm/yyyy-hh:mm + """ + import datetime + timestamp = datetime.datetime.fromtimestamp(pretimestamp) + timestamp = timestamp.strftime("%d/%m/%Y-%H:%M:%S") + return timestamp + + def flaskrender(self): + """ + Render the note as html for flask, using flask.Markup + """ + import markdown + from flask import Markup + + rendered = f""" +
+
{Markup.escape(self.title)}
+
+ | +
+
Created : {self.rendertime(self.createtime)} +
Modified : {self.rendertime(self.modtime)}

+
{markdown.markdown(self.text, extensions=['fenced_code', 'codehilite', 'nl2br', 'smarty'])}

+ """ + return Markup(rendered) + + def __str__(self): + return self.title diff --git a/src/funcs.py b/src/funcs.py new file mode 100644 index 0000000..2251222 --- /dev/null +++ b/src/funcs.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +#coding: utf-8 +from classes import note + +def mknotedir(): + """ + Create our data directory if does not exist. + """ + from os.path import exists + from os import mkdir + + if not exists("./data"): + mkdir("./data") + +def dumpnotes(notes): + """ + Get our notes list and save them as pickle to notes.pickle + """ + import pickle + with open('./data/notes.pickle', 'wb') as mpf: + pickle.dump(notes, mpf) + + return True + +def getnotes(): + """ + Get our notes from the file notes.pickle + """ + from os.path import exists + import pickle + + if exists("./data/notes.pickle"): + with open('./data/notes.pickle', 'rb') as mpf: + notes = pickle.load(mpf) + else: + notes = [] + + return notes + +def catnotes(notelist: list): + """ + Concatenate a list of notes into a str. + """ + final = "" + for note in notelist: + final += note.flaskrender() + + return final + +def delnote(timestamp: int): + """ + Delete note in our pickle file for which the createtime corresponds to timestamp + """ + notes = getnotes() + for note in notes: + if int(note.createtime) == int(timestamp): + notes.remove(note) + dumpnotes(notes) + return True + return False + +def findnote(createtime: int): + """ + Find a note in our pickle file of notes by its createtime + """ + notes = getnotes() + for note in notes: + if note.createtime == createtime: + return note + +def addnote(mynote: note): + """ + Add a note to our notes pickle file (and sort it). + """ + notes = getnotes() + notes.append(mynote) + notes = sorted(notes, key=lambda note: note.modtime, reverse=True) + dumpnotes(notes) diff --git a/src/notes.pickle b/src/notes.pickle deleted file mode 100644 index 4ccd3924117e914de42bd7c25ad0a861b2a8aa34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 zcmYk1%SyvQ6owV*g@Jj8L%V1Tl7dT@?i9LmBS=Xn$!RlmE+KPj8br{w**QLv@8xMM z+FAW`F5my3x53xP=}G?Z86?|zg%aX$ZJ%D zN0l?uWH5H;^S1JV7(lqA_;|(ir+I6%+bkv}Q59}xv!-d1wfAd-$*P`8A;k!8^%{DH z6n6wVfYUhwdB_k{X7*BwZQu_C?RXWKi5chEfN}){(#Alkp7#@ft)4xC2dlVwz_%Er z7*oj}q4Zl*0N>i%KvjFTvSS$j8kb}ZQf*)n(5%M)^L+2<5DM#~Sez_wGnM=R=un4(