From 43eae3a4a86db4878b670b7efc14e01bd4c06e0f Mon Sep 17 00:00:00 2001 From: blendoit Date: Wed, 5 Feb 2020 19:47:05 -0800 Subject: 'yes' page styles. --- Pipfile | 3 +- Pipfile.lock | 24 +++-- README.org | 16 ++- README.pdf | Bin 176463 -> 198166 bytes README.tex | 55 ++++++---- app/placeholder_messages.py | 228 +++++++++++++++++++++++++++++++++++------- app/routes.py | 6 +- app/static/styles/default.css | 2 +- app/static/styles/home.css | 4 +- app/static/styles/yes.css | 177 +++++++++++++++++++++++--------- app/templates/home.html | 2 - app/templates/yes.html | 101 +++++++++++-------- 12 files changed, 450 insertions(+), 168 deletions(-) diff --git a/Pipfile b/Pipfile index 15e2a5d..47b16c4 100644 --- a/Pipfile +++ b/Pipfile @@ -11,8 +11,7 @@ flask-wtf = "*" uwsgi = "*" flask-socketio = "*" flask-sqlalchemy = "*" -pymysql = "*" -sqlalchemy = "*" +psycopg2 = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 81a40a9..0fb0f26 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "45e0b8d6a2539692d1e7c95574a2ab2b419bd7d2ea86d84b5ee2a23e23dca9af" + "sha256": "9da6e208bd9f0c1e21efeea29b22ff142961469889f826c3e4404a3930b487d0" }, "pipfile-spec": 6, "requires": { @@ -107,13 +107,24 @@ ], "version": "==1.1.1" }, - "pymysql": { - "hashes": [ - "sha256:3943fbbbc1e902f41daf7f9165519f140c4451c179380677e6a848587042561a", - "sha256:d8c059dcd81dedb85a9f034d5e22dcb4442c0b201908bede99e306d65ea7c8e7" + "psycopg2": { + "hashes": [ + "sha256:4212ca404c4445dc5746c0d68db27d2cbfb87b523fe233dc84ecd24062e35677", + "sha256:47fc642bf6f427805daf52d6e52619fe0637648fe27017062d898f3bf891419d", + "sha256:72772181d9bad1fa349792a1e7384dde56742c14af2b9986013eb94a240f005b", + "sha256:8396be6e5ff844282d4d49b81631772f80dabae5658d432202faf101f5283b7c", + "sha256:893c11064b347b24ecdd277a094413e1954f8a4e8cdaf7ffbe7ca3db87c103f0", + "sha256:92a07dfd4d7c325dd177548c4134052d4842222833576c8391aab6f74038fc3f", + "sha256:965c4c93e33e6984d8031f74e51227bd755376a9df6993774fd5b6fb3288b1f4", + "sha256:9ab75e0b2820880ae24b7136c4d230383e07db014456a476d096591172569c38", + "sha256:b0845e3bdd4aa18dc2f9b6fb78fbd3d9d371ad167fd6d1b7ad01c0a6cdad4fc6", + "sha256:dca2d7203f0dfce8ea4b3efd668f8ea65cd2b35112638e488a4c12594015f67b", + "sha256:ed686e5926929887e2c7ae0a700e32c6129abb798b4ad2b846e933de21508151", + "sha256:ef6df7e14698e79c59c7ee7cf94cd62e5b869db369ed4b1b8f7b729ea825712a", + "sha256:f898e5cc0a662a9e12bde6f931263a1bbd350cfb18e1d5336a12927851825bb6" ], "index": "pypi", - "version": "==0.9.3" + "version": "==2.8.4" }, "python-engineio": { "hashes": [ @@ -140,7 +151,6 @@ "hashes": [ "sha256:64a7b71846db6423807e96820993fa12a03b89127d278290ca25c0b11ed7b4fb" ], - "index": "pypi", "version": "==1.3.13" }, "uwsgi": { diff --git a/README.org b/README.org index 4197c41..4864a78 100644 --- a/README.org +++ b/README.org @@ -1,7 +1,6 @@ #+TITLE: README.org for =yesno= #+AUTHOR: Marius P. and Vaqar S. -#+DATE: 22 Jan. 2020 -#+LATEX_HEADER: \usepackage{fullpage} +#+DATE: Created: <2020-01-22 Wed> \break Updated: <2020-02-05 Wed> * Folder structure @@ -39,12 +38,21 @@ * Prerequisites 1. A Python interpreter and the following dependencies: - 1. =Flask= + | Dependency | Minimum version | + |--------------------+-----------------| + | =flask= | | + | =flask-wtf= | | + | =uwsgi= | | + | =flask-socketio= | | + | =flask-sqlalchemy= | | + | =psycopg2= | | + 2. A web browser * Installation - Install Python. + 1. Install Python + 2. Install dependencies * Viewing the website diff --git a/README.pdf b/README.pdf index 9859189..b8d2bbf 100644 Binary files a/README.pdf and b/README.pdf differ diff --git a/README.tex b/README.tex index 0483e29..e133238 100644 --- a/README.tex +++ b/README.tex @@ -1,4 +1,4 @@ -% Created 2020-01-22 Wed 20:21 +% Created 2020-02-05 Wed 15:56 % Intended LaTeX compiler: pdflatex \documentclass[11pt]{article} \usepackage[utf8]{inputenc} @@ -14,9 +14,8 @@ \usepackage{amssymb} \usepackage{capt-of} \usepackage{hyperref} -\usepackage{fullpage} \author{Marius P. and Vaqar S.} -\date{22 Jan. 2020} +\date{Created: \textit{<2020-01-22 Wed> } \break Updated: \textit{<2020-02-05 Wed>}} \title{README.org for \texttt{yesno}} \hypersetup{ pdfauthor={Marius P. and Vaqar S.}, @@ -32,69 +31,83 @@ \section{Folder structure} -\label{sec:org7993fb5} +\label{sec:org077247d} \subsection{\texttt{Pipfile}} -\label{sec:org80836f9} +\label{sec:org4222668} Inspecting this file reveals the Python dependencies required by the Flask application. The convenient \texttt{pipenv} Python package bundles together the creation of virtual environments and populating these virtual environments using the same commands as \texttt{pip}. For more information on \texttt{pipenv}, visit \href{https://github.com/pypa/pipenv}{the official pipenv page}. \subsection{\texttt{Pipfile.lock}} -\label{sec:orgf06ab89} +\label{sec:org425064c} This file contains checksums for the packages installed via \texttt{pipenv}. \subsection{\texttt{README.org}} -\label{sec:org1715543} +\label{sec:orgdff75cc} This is the file you are currently reading. Github automatically formats README files and presents underneath the code explorer. \subsection{\texttt{app} directory} -\label{sec:org67d9e1d} +\label{sec:orgac83665} Contains \texttt{.py} Python scripts calling the \texttt{Flask} library in order to serve web pages to the end user. \subsubsection{\texttt{static}} -\label{sec:org250fc10} +\label{sec:orgb2e5456} Static files and assets do not change during the \texttt{Flask} application's execution. \begin{enumerate} \item \texttt{img} -\label{sec:org6b963c3} +\label{sec:org7afe92f} This is where website images are saved. User images will be stored in a database, which is currently not implemented. \item \texttt{styles} -\label{sec:org860737a} +\label{sec:org4bfb4f4} Here, we store \texttt{CSS} style sheets. These contain appearance information for elements described in \texttt{HTML} documents. \end{enumerate} \subsubsection{\texttt{templates}} -\label{sec:orgae70d36} +\label{sec:org4f7742b} In the templates folder, we organise our \texttt{HTML} templates. Rather than simple \texttt{HTML} documents which always present the same content to all users, templates are rendered to the user's browser by the application and are populated during loading with content we can request via the Python application. \subsubsection{\texttt{routes.py}} -\label{sec:orge3ac7eb} +\label{sec:org691e421} This Python file containes our website routes. These are the names of our website's pages, followed by functions describing actions performed on the server side every time a user visits a certain page. \subsubsection{\texttt{forms.py}} -\label{sec:org934f5b3} +\label{sec:org18bbfe0} This Python file contains the forms that our user will sign in throughout the website (registration, login). Possible implementation of the messaging system as a series of forms sent from user to user. \section{Prerequisites} -\label{sec:orgf8c00d7} +\label{sec:org37f495c} \begin{enumerate} \item A Python interpreter and the following dependencies: -\begin{enumerate} -\item \texttt{Flask} -\end{enumerate} +\begin{center} +\begin{tabular}{ll} +Dependency & Minimum version\\ +\hline +\texttt{flask} & \\ +\texttt{flask-wtf} & \\ +\texttt{uwsgi} & \\ +\texttt{flask-socketio} & \\ +\texttt{flask-sqlalchemy} & \\ +\texttt{psycopg2} & \\ +\end{tabular} + +\end{center} + \item A web browser \end{enumerate} \section{Installation} -\label{sec:org41d3c46} +\label{sec:org4f8f49c} -Install Python. +\begin{enumerate} +\item Install Python +\item Install dependencies +\end{enumerate} \section{Viewing the website} -\label{sec:orgff7b5c7} +\label{sec:org61e9d73} \begin{enumerate} \item Run the \texttt{routes.py} script using your Python interpreter. diff --git a/app/placeholder_messages.py b/app/placeholder_messages.py index 6225859..b48c3a6 100644 --- a/app/placeholder_messages.py +++ b/app/placeholder_messages.py @@ -1,39 +1,199 @@ -messages = [{ - 'author': 'A.Banyan_97', - 'date': 'Dec. 26th, 2019', - 'content': "How is it going?" +conversations = [{ + 'title': 'Code meee', + 'messages': { + '1': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Yo tryna code tonight?' + }, + '2': { + 'author': 'blendoit', + 'date': 'Jan. 31st 2020', + 'content': 'Sure, what time are you tryna meet up?' + }, + '3': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Maybe 8 or 9 sara7a.' + }, + '4': { + 'author': + 'blendoit', + 'date': + 'Jan. 31st 2020', + 'content': + 'Perfect, I should be done with this fluid mechanics homework in the meantime, ah.' + }, + '5': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Ok cool, see you then.' + } + } }, { - 'author': 'itsgeorgeeid', - 'date': 'Dec. 25th, 2019', - 'content': "Bas man we should have a private sesh." + 'title': 'Second Convo', + 'messages': { + '1': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Yo tryna code tonight?' + }, + '2': { + 'author': 'blendoit', + 'date': 'Jan. 31st 2020', + 'content': 'Sure, what time are you tryna meet up?' + }, + '3': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Maybe 8 or 9 sara7a.' + }, + '4': { + 'author': + 'blendoit', + 'date': + 'Jan. 31st 2020', + 'content': + 'Perfect, I should be done with this fluid mechanics homework in the meantime, ah.' + }, + '5': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Ok cool, see you then.' + } + } }, { - 'author': 'Country_V', - 'date': 'Dec. 24th, 2019', - 'content': "Have you checked out Young Thug's latest leak?!" + 'title': 'Third Convo', + 'messages': { + '1': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Yo tryna code tonight?' + }, + '2': { + 'author': 'blendoit', + 'date': 'Jan. 31st 2020', + 'content': 'Sure, what time are you tryna meet up?' + }, + '3': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Maybe 8 or 9 sara7a.' + }, + '4': { + 'author': + 'blendoit', + 'date': + 'Jan. 31st 2020', + 'content': + 'Perfect, I should be done with this fluid mechanics homework in the meantime, ah.' + }, + '5': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Ok cool, see you then.' + } + } }, { - 'author': - 'Blendoit', - 'date': - 'Dec. 26th, 2019', - 'content': - "Ah, I'm creating a new website with a friend from college, how about you?" + 'title': 'Fourth Convo', + 'messages': { + '1': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Yo tryna code tonight?' + }, + '2': { + 'author': 'blendoit', + 'date': 'Jan. 31st 2020', + 'content': 'Sure, what time are you tryna meet up?' + }, + '3': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Maybe 8 or 9 sara7a.' + }, + '4': { + 'author': + 'blendoit', + 'date': + 'Jan. 31st 2020', + 'content': + 'Perfect, I should be done with this fluid mechanics homework in the meantime, ah.' + }, + '5': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Ok cool, see you then.' + } + } }, { - 'author': 'BChon', - 'date': 'Jan. 26th, 2019', - 'content': "yo wassap" -}, { - 'author': 'Blendoit', - 'date': 'Dec. 26th, 2019', - 'content': "Ah why aren't you replying" -}, { - 'author': 'vaqarsyed', - 'date': 'Jan. 14th, 2019', - 'content': "Hrr, another day on the grind #slatt" -}, { - 'author': - 'christinafarhat', - 'date': - 'Dec. 26th, 2019', - 'content': - "I'm just using the first name that comes to mind at this point." + 'title': 'Fifth Convo', + 'messages': { + '1': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Yo tryna code tonight?' + }, + '2': { + 'author': 'blendoit', + 'date': 'Jan. 31st 2020', + 'content': 'Sure, what time are you tryna meet up?' + }, + '3': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Maybe 8 or 9 sara7a.' + }, + '4': { + 'author': + 'blendoit', + 'date': + 'Jan. 31st 2020', + 'content': + 'Perfect, I should be done with this fluid mechanics homework in the meantime, ah.' + }, + '5': { + 'author': 'vaqarsyed', + 'date': 'Jan. 31st 2020', + 'content': 'Ok cool, see you then.' + } + } }] +# 'author': 'A.Banyan_97', +# 'date': 'Dec. 26th, 2019', +# 'content': "How is it going?" +# }, { +# 'author': 'itsgeorgeeid', +# 'date': 'Dec. 25th, 2019', +# 'content': "Bas man we should have a private sesh." +# }, { +# 'author': 'Country_V', +# 'date': 'Dec. 24th, 2019', +# 'content': "Have you checked out Young Thug's latest leak?!" +# }, { +# 'author': +# 'Blendoit', +# 'date': +# 'Dec. 26th, 2019', +# 'content': +# "Ah, I'm creating a new website with a friend from college, how about you?" +# }, { +# 'author': 'BChon', +# 'date': 'Jan. 26th, 2019', +# 'content': "yo wassap" +# }, { +# 'author': 'Blendoit', +# 'date': 'Dec. 26th, 2019', +# 'content': "Ah why aren't you replying" +# }, { +# 'author': 'vaqarsyed', +# 'date': 'Jan. 14th, 2019', +# 'content': "Hrr, another day on the grind #slatt" +# }, { +# 'author': +# 'christinafarhat', +# 'date': +# 'Dec. 26th, 2019', +# 'content': +# "I'm just using the first name that comes to mind at this point." +# }] diff --git a/app/routes.py b/app/routes.py index 67b9359..301a8a8 100644 --- a/app/routes.py +++ b/app/routes.py @@ -23,7 +23,7 @@ from flask_sqlalchemy import SQLAlchemy from placeholder_posts import posts from placeholder_news import news -from placeholder_messages import messages +from placeholder_messages import conversations app = Flask(__name__) app.config['SECRET_KEY'] = 'Scooby_Lu,_where_are_you?' @@ -62,14 +62,14 @@ class Post(db.Model): @app.route("/home") def home(): """This is our homepage.""" - home_posts = posts + news + messages + home_posts = posts + news + conversations return render_template('home.html', posts=home_posts) @app.route("/yes") def yes(): """Another page, presenting the user with content marked as 'yes'.""" - return render_template("yes.html", messages=messages, news=news) + return render_template("yes.html", conversations=conversations, news=news) @app.route("/no") diff --git a/app/static/styles/default.css b/app/static/styles/default.css index 3812189..05413f6 100644 --- a/app/static/styles/default.css +++ b/app/static/styles/default.css @@ -1,7 +1,7 @@ :root { --primary-color: #003B5C; --secondary-color: #C3D7EE; - --home: rgba(200, 200, 200, 0.7); + --home: #c8c8c8; --yes: #5cff5c; --no: #ff5c5c; font-size: 18; diff --git a/app/static/styles/home.css b/app/static/styles/home.css index 290909f..161abc8 100644 --- a/app/static/styles/home.css +++ b/app/static/styles/home.css @@ -1,7 +1,7 @@ /* Tabs. */ .tab-yes { height: 100%; - width: 10%; + width: 6%; position: absolute; left: 0; background: var(--yes); @@ -15,7 +15,7 @@ } .tab-no { height: 100%; - width: 10%; + width: 6%; position: absolute; right: 0; background: var(--no); diff --git a/app/static/styles/yes.css b/app/static/styles/yes.css index bcaf7a4..cd0970f 100644 --- a/app/static/styles/yes.css +++ b/app/static/styles/yes.css @@ -1,72 +1,113 @@ -/* Main page area. */ :root {background: var(--yes);} - -.main { +/* Feeds wrapper. */ +.feeds { height: 100%; - position: relative; - z-index: 0; + width: calc(100% - 6%); + position: absolute; overflow: hidden; - /* animation-name: yes-refresh; */ - /* animation-duration: var(--slow-speed); */ + animation-name: yes-refresh; + animation-duration: var(--med-speed); } - /* Tabs. */ .tab-no { height: 100%; width: 3%; - position: absolute; - right: 0; + position: relative; + float: right; + z-index: 0; background: var(--no); - /* animation-name: yes-refresh; */ - /* animation-duration: var(--slow-speed); */ } +.tab-no:hover {width: 6%; transition: var(--fast-speed);} +.tab-no:hover ~ .tab-home {width: 6%; transition: var(--fast-speed);} +.tab-no:hover ~ .feeds {right: 12%; transition: var(--fast-speed);} .tab-home { height: 100%; width: 3%; + position: relative; float: right; - position: absolute; - /* background: var(--home); */ - /* animation-name: yes-refresh; */ - animation-duration: var(--slow-speed); + z-index: 1; + background: var(--home); } -.tab-home:hover { - width: 4%; - transition: 0.2s; +.tab-home:hover {width: 6%; transition: var(--fast-speed);} +.tab-home:hover ~ .feeds { + /* left: -3%; */ + right: 9%; + transition: var(--fast-speed); } -.tab-no:hover ~ .tab-home { - width: 5%; - transition: 0.2s; -} -.tab-no:hover { - width: 4%; - transition: 0.2s; -} - /* Feeds. */ -.feed-message { +.feed-conversations { height: 100%; - width: 25%; + width: 30%; position: relative; float: left; overflow: auto; } -.message { +.conversation-wrapper { + /* background: blue; */ + height: 25%; + position: relative; + margin: 1rem; + overflow: hidden; + perspective: 600px; +} +.conversation-wrapper:hover { + height: 40%; + transition-duration: var(--med-speed); +} +.btn-reply { + height: 3rem; + width: calc(50% - 1rem); + position: absolute; + left: 0; + background: var(--home); + border-radius: 8px; + transform: rotateX(90deg); + transition-duration: var(--slow-speed); + transform-origin: bottom; +} +.conversation-wrapper:hover > .btn-reply {transform: rotateX(0deg);} +.btn-finish { + height: 3rem; + width: calc(50% - 1rem); + position: absolute; + right: 0; + background: var(--no); + border-radius: 8px; + transform: rotateX(90deg); + transition-duration: var(--slow-speed); + transform-origin: bottom; +} +.conversation-wrapper:hover > .btn-finish {transform: rotateX(0deg);} +.conversation { + height: 40%; + width: 100%; + position: relative; background: white; - border-radius: 14px; - padding: 1rem; - margin: 0.5rem; + border-radius: 12px; + overflow: hidden; + transition-duration: var(--med-speed); } -.message:hover { - background: linear-gradient(to left, var(--no) 50%, var(--yes) 50%); - cursor: pointer; - transition: 0.8s; - color: white; +.conversation-wrapper:hover > .conversation { + margin-top: 3.5rem; + overflow: auto; +} +.input[type=text] { + width: 70%; + position: relative; + margin: 0 auto; + /* transform: rotateX(-90deg); */ + transition-duration: var(--slow-speed); + transform-origin: top; +} +conversation-wrapper:hover > .input[type=text] { + transform: rotateX(90deg); + width: 20%; } .feed-news { height: 100%; - width: 55%; + width: 50%; display: flex; position: relative; float: left; @@ -74,27 +115,63 @@ overflow: auto; justify-content: space-between; } +.news-wrapper { + /* background: blue; */ + height: 25%; + max-width: 40%; + position: relative; + margin: 1rem; + overflow: hidden; + perspective: 600px; +} +.news-wrapper:hover { + height: 25%; + transition-duration: var(--med-speed); +} .news { - max-height: 10%; - max-width: 50%; + height: 100%; + max-width: 100%; background: white; position: relative; border-radius: 14px; - padding: 1rem; - margin: 0.5rem; overflow: hidden; + transition-duration: var(--med-speed); } -.news:hover { - background: linear-gradient(to left, var(--no) 50%, var(--yes) 50%); - cursor: pointer; - transition: 0.8s; - color: white; +.news-wrapper:hover > .news { + overflow: auto; +} +.btn-comment { + height: 3rem; + width: calc(50% - 1rem); + position: absolute; + left: 0; + background: var(--home); + border-radius: 8px; + transform: rotateX(90deg); + transition-duration: var(--slow-speed); + transform-origin: bottom; +} +.news-wrapper:hover > .btn-comment {transform: rotateX(0deg);} +.btn-archive { + height: 3rem; + width: calc(50% - 1rem); + position: absolute; + right: 0; + background: var(--no); + border-radius: 8px; + transform: rotateX(90deg); + transition-duration: var(--slow-speed); + transform-origin: bottom; +} +.news-wrapper:hover > .btn-archive {transform: rotateX(0deg);} +.news-wrapper:hover > .news { + margin-top: 3.5rem; overflow: auto; } .feed-ads { - height: 100%; width: 20%; + height: 100%; position: relative; float: right; overflow: auto; diff --git a/app/templates/home.html b/app/templates/home.html index 5598739..6363601 100644 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -4,9 +4,7 @@ {% extends "base.html" %} {% block content %} - -
diff --git a/app/templates/yes.html b/app/templates/yes.html index 3ccc24b..9a2fff3 100644 --- a/app/templates/yes.html +++ b/app/templates/yes.html @@ -4,61 +4,78 @@ {% extends "base.html" %} {% block content %} -
- - + + -
+
+
+ {% for conversation in conversations %} +
+ reply + finish conversation +
+ {% if 'title' in conversation %} +

{{conversation.title}}

+ {% endif %} + + + +
+

author 1

+

message received

+
+
+

me

+

message received

+
+
+

author 1

+

message received

+
+
+

me

+

message received

+
+
+

author 1

+

message received

+
+
+

me

+

last message received

+
-
- {% for message in messages %} -
-

{{message.author}}

-

{{message.date}}

-

{{message.content}}

- {% endfor %} +
+ {% endfor %} + +
-
- {% for news in news %} +
+ {% for news in news %} +
+ comment + archive

{{news.author}}

{{news.date}}

{{news.content}}

- {% endfor %}
+ {% endfor %} +
-
-
- Buy my sourdough, ah -
-
- Check out this sponsored link, ere. -
-
- Another random ad (from a high-paying sponsor hopefully) -
-
- Ah I literally don't have any other placeholder ideas for ads. -
-
- Buy my sourdough, ah -
-
- Check out this sponsored link, ere. -
-
- Another random ad (from a high-paying sponsor hopefully) -
-
- Ah I literally don't have any other placeholder ideas for ads. -
-
-
+
+
Buy my sourdough, ah
+
Check out this sponsored link, ere.
+
Another random ad (from a high-paying sponsor hopefully)
+
Ah I literally don't have any other placeholder ideas for ads.
+
Buy my sourdough, ah
+
Check out this sponsored link, ere.
+
Another random ad (from a high-paying sponsor hopefully)
+
Ah I literally don't have any other placeholder ideas for ads.
- {% endblock content %} -- cgit v1.2.3