Compare commits

...

3 Commits

File diff suppressed because one or more lines are too long

@ -0,0 +1,22 @@
from string import ascii_uppercase
def generate_grid(word, origin, direction):
start = (
ascii_uppercase.index(origin[0]),
int(origin[1:]),
)
cells = []
for i in range(len(word)):
if direction == "H":
# increase number
start_f = f"{ascii_uppercase[start[0]]}{start[1] + i}"
pass
else:
# increase letter
start_f = f"{ascii_uppercase[start[0] + i]}{start[1]}"
pass
cells.append(start_f)
return cells

@ -1,133 +1,107 @@
import json
import frontmatter
import os
import string
from . import crossword
def dump(order=None):
# list all the folders
path = "postit/static/contents"
# The function can receive an optional order for the contents
# in the form of a list of folder like
# ['intro','what-is-a-loot-box', 'crosswords', 'one-sentence-game-ideas', 'nim', 'mimic', 'unfinished-thoughts', 'the-leader', 'connect-less', 'xquisite', 'katamari', 'life-hacks', 'karaoke', 'outro']
folders = order
path = "postit/static/contents"
if folders == None:
# If no order is passed, list all the folders in the contents directory
folders = [f.name for f in os.scandir(path) if f.is_dir()]
contents = {}
# Total number of postit
total = 0
# Dictionary to fill with the contributions
contents = {}
for folder in folders:
# Initialize the contribution as an empty list of postit
contribution = []
try:
# Load the file from a contents.md file
# (we are intrested only in the yaml metadata tho)
with open(f"{path}/{folder}/contents.md", "r", encoding="utf8") as f:
metadata, body = frontmatter.parse(f.read())
for content in metadata["contents"]:
# For each entry in the contents list create a default postit dictionary
# with the title of the contribution
postit = {
'title' : metadata['title']
}
# We have basically 2 types of postit:
# 1. Simple postit with just a string of text
# 2. Complex postit with different informations
# ii) We start from this second kind, that is loaded as a dictionary
if type(content) == dict:
# Pass all the properties from the yaml object to the post-it dictionary
for key in content:
postit[key] = content[key]
# --------------------------
# Custom post-it generation
# Add here the function for generate dynamic postit
# (such as the crossword imaginary grid)
if "img" in content:
postit = {
"title": metadata["title"],
"description": content["alt"],
"img": content["img"],
"slug": folder,
}
# this is temporary, sorry
elif "type" in content:
if content["type"] == 'mimic-colophon':
postit = {
"title": metadata['title'],
"type": content['type'],
"original": content['original'],
"original-credits": content['original-credits'],
"original-action": content['original-action'],
"original-date": content['original-date'],
"current": content['current'],
'current-credits': content['current-credits'],
"current-action": content['current-action'],
"current-date": content['current-date'],
"slug": folder,
}
elif "card" in content:
postit = {
"title": metadata["title"],
"card": content["card"],
"quote": content["quote"],
"motivation": content["motivation"],
"vision": content["vision"],
"empathy": content["empathy"],
"positivity": content["positivity"],
"slug": folder,
}
elif any(position in ['nw','ne','sw','se'] for position in content):
postit = {
"title": metadata["title"],
"slug": folder,
}
for position in content:
postit[position] = content[position]
elif "word" in content and content['category'] != 'Loot Box':
# Generate the Imaginary Grid for the Crossword game
# (Only for the Loot Box category)
if "word" in content and content['category'] != 'Loot Box':
continue
elif "word" in content:
postit = {
"title": metadata["title"],
"definition": content["definition"],
"category": content["category"],
"start": content["start"],
"word": content["word"],
"direction": content["direction"],
"slug": folder,
}
if content["word"]:
start = (
string.ascii_uppercase.index(content["start"][0]),
int(content["start"][1:]),
)
# print(start)
for i in range(len(content["word"])):
if content["direction"] == "H":
# increase number
start_f = f"{string.ascii_uppercase[start[0]]}{start[1] + i}"
# print(start_f)
pass
else:
# increase letter
start_f = f"{string.ascii_uppercase[start[0] + i]}{start[1]}"
# print(start_f)
pass
# Generate a postit for each letter in the word
for cell in crossword.generate_grid(content['word'], content["start"], content["direction"]):
contribution.append(
{
"title": metadata["title"],
"definition": " ",
"category": content["category"],
"start": start_f,
"word": content["word"],
"direction": content["direction"],
"slug": folder,
}
)
"start": cell,
})
#----------------------------
else:
postit = {
"title": metadata["title"],
"description": content,
"slug": folder,
}
# i) Simple string postit
postit["description"] = content
# Add the postit to the contribution
contribution.append(postit)
# Log the amount of postit for the current contribution
amount = len(contribution)
print(f"{amount:03} - {folder}")
# Add the contribution to the total amount
total = total + amount
# Add the contribution to the contents object
contents[folder] = contribution
except Exception as e:
# If a markdown file is broken print the error and move on
# without breaking everything
print(f"{folder} has an error!")
print(e)
print(f'Total: {total}')
# Store the postit in a JSON file
# in order to avoid repeating this process everytime we want the postit.
with open("postit/contents.json", "w") as f:
f.write(json.dumps(contents))

@ -1,9 +1,23 @@
from flask import Blueprint, render_template, send_from_directory
from flask import Blueprint, render_template, request
import json
from . import dump
import os
index = ['intro','what-is-a-loot-box', 'crosswords', 'one-sentence-game-ideas', 'nim', 'mimic', 'unfinished-thoughts', 'the-leader', 'connect-less', 'xquisite', 'katamari', 'life-hacks', 'karaoke', 'outro']
index = [
"intro",
"what-is-a-loot-box",
"crosswords",
"one-sentence-game-ideas",
"nim",
"mimic",
"unfinished-thoughts",
"the-leader",
"connect-less",
"xquisite",
"katamari",
"life-hacks",
"karaoke",
"outro",
]
bp = Blueprint(
@ -15,20 +29,25 @@ bp = Blueprint(
@bp.route("/")
def blocks():
# temporary, eventually we will dump contents only when they are updated (git hooks + git pull ?)
color = request.cookies.get("color", "purple")
# temporary, eventually we will dump contents only when they are updated in git (git hooks + git pull ?)
dump.dump(index)
with open("postit/contents.json", "r") as f:
contributions = json.load(f)
return render_template("postit.html", contributions=contributions)
return render_template("postit.html", contributions=contributions, color=color)
@bp.route("/<slug>")
def block(slug=None):
color = request.cookies.get("color", "purple")
dump.dump([slug])
with open("postit/contents.json", "r") as f:
contributions = json.load(f)
return render_template("postit.html", contributions=contributions)
return render_template("postit.html", contributions=contributions, color=color)

@ -1,15 +1,15 @@
from flask import Blueprint, render_template, request, url_for
import os
from flask import Blueprint, render_template
# import os
bp = Blueprint("home", __name__, url_prefix="/")
index = ['intro','what-is-a-loot-box', 'crosswords', 'one-sentence-game-ideas', 'nim', 'mimic', 'unfinished-thoughts', 'the-leader', 'connect-less', 'xquisite', 'katamari', 'life-hacks', 'karaoke', 'outro']
pages = ['intro','what-is-a-loot-box', 'crosswords', 'one-sentence-game-ideas', 'nim', 'mimic', 'unfinished-thoughts', 'the-leader', 'connect-less', 'xquisite', 'katamari', 'life-hacks', 'karaoke', 'outro']
@bp.route("/")
def home():
# path = "postit/static/contents"
# pages = [f.name for f in os.scandir(path) if f.is_dir()]
# path = "postit/static/contents"
# pages = [f.name for f in os.scandir(path) if f.is_dir()]
return render_template("home.html", pages=index)
return render_template("home.html", pages=pages)

@ -1 +1 @@
Subproject commit 1691c432b0126c3adc4c292e66c6efd9032f14f5
Subproject commit 08d68b497fb2fa47d7d9f74c86600a0b01b7566b

@ -74,10 +74,6 @@
font-size: 24px;
}
.connect-less figcaption {
display: none;
}
.crosswords .info {
position: absolute;
font-size: 21px;
@ -127,8 +123,7 @@
}
.nw {
white-space: initial;
white-space: initial;
}
.ne {
@ -145,3 +140,7 @@
.sw {
margin-top: auto;
}
.outro figcaption {
font-size: 14px;
}

@ -0,0 +1,22 @@
:root {
--color: var(--purple);
--background: var(--purple-bg);
--alt: var(--orange);
--alt-bg: var(--orange-bg);
--orange: #ff5416;
--orange-bg: #ffb58d;
--purple: #7d50ff;
--purple-bg: #cec6ff;
}
html,
body {
margin: 0;
color: var(--color);
}
* {
box-sizing: border-box;
}

@ -0,0 +1,49 @@
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 24px;
line-height: 1.4;
color: var(--color);
padding: 32px;
}
a {
color: currentColor;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1,
h2,
h3 {
font-size: 24px;
}
h3 {
font-weight: normal;
margin: 0;
}
ol {
margin: 0;
}
button#color {
position: absolute;
right: 32px;
top: 52px;
display: inline-block;
width: 24px;
height: 24px;
border-radius: 0;
border: none;
background-color: var(--alt-bg);
}
button#color:hover {
transition: transform 0.1s ease-out;
transform: scale(1.05);
cursor: pointer;
}

@ -5,27 +5,6 @@
/* marks: crop; */
}
:root {
--color: var(--orange);
--background: var(--orange-bg);
--orange: #FF5416;
--orange-bg: #FFB58D;
--purple: #7D50FF;
--purple-bg: #CEC6FF;
}
html,
body {
margin: 0;
color: var(--color);
}
* {
box-sizing: border-box;
}
.post-it {
position: relative;
vertical-align: middle;
@ -35,8 +14,6 @@ body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
line-height: 1.4;
/* overflow: hidden;
text-overflow: ellipsis; */
display: inline-flex;
justify-content: end;
flex-direction: column;
@ -45,10 +22,8 @@ body {
footer {
width: 100%;
position: relative;
/* position: absolute; */
/* bottom: 0; */
border-top: 1px solid var(--background);
overflow:visible;
overflow: visible;
}
img {
@ -62,13 +37,7 @@ img {
z-index: 50;
}
/* img::after {
content: " " url("/static/contents/katamari/frog.png");
} */
.title {
/* position: absolute; */
/* bottom: 0; */
margin: 0.25em 4mm;
font-weight: normal;
text-transform: uppercase;
@ -83,7 +52,6 @@ img {
font-size: 28px;
line-height: 1.2;
white-space: pre-line;
/* margin-top: calc(4mm - 1em); */
vertical-align: bottom;
}

@ -0,0 +1,50 @@
// I really don't like this code but it's ok for now...
let main = true;
// Set a reference in the localStorage with the main color
window.addEventListener("load", () => {
color = getCookie("color");
if (color == "purple" || color == "") {
document.documentElement.style.setProperty("--color", "var(--purple)");
document.documentElement.style.setProperty("--background", "var(--purple-bg)");
document.documentElement.style.setProperty("--alt", "var(--orange)");
document.documentElement.style.setProperty("--alt-bg", "var(--orange-bg)");
setCookie("color", "purple", 7);
main = true;
} else {
document.documentElement.style.setProperty("--color", "var(--orange)");
document.documentElement.style.setProperty("--background", "var(--orange-bg)");
document.documentElement.style.setProperty("--alt", "var(--purple)");
document.documentElement.style.setProperty("--alt-bg", "var(--purple-bg)");
setCookie("color", "orange", 7);
main = false;
}
});
// Toggle color button
const colorButton = document.getElementById("color");
colorButton.addEventListener("click", () => {
toggleColor();
});
function toggleColor() {
var style = getComputedStyle(document.body);
// get the current palette
currentColor = style.getPropertyValue("--color");
currentBg = style.getPropertyValue("--background");
altColor = style.getPropertyValue("--alt");
altBg = style.getPropertyValue("--alt-bg");
// and swap the order
document.documentElement.style.setProperty("--color", altColor);
document.documentElement.style.setProperty("--background", altBg);
document.documentElement.style.setProperty("--alt", currentColor);
document.documentElement.style.setProperty("--alt-bg", currentBg);
// set a reference in a cookie to share it with the generator page
main = !main;
setCookie("color", main ? "purple" : "orange", 7);
}

@ -0,0 +1,22 @@
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function eraseCookie(name) {
document.cookie = name + "=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
}

@ -4,19 +4,27 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{{url_for('static', filename='css/global.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/home.css')}}" />
<script src="{{url_for('static', filename='js/cookies.js')}}"></script>
<script src="{{url_for('static', filename='js/color.js')}}" defer></script>
<title>Post-it</title>
</head>
<body>
<h1>🚩 90 000 post-it</h1>
<ul>
<h1>🚩 85 000 post-it</h1>
<h2><a class="generate all" href="{{url_for('generate.blocks')}}">Generate all</a></h2>
<button id="color"></button>
<h3>Contribution</h3>
<ol>
{%for page in pages %}
<li>
<a href="{{url_for('generate.block', slug=page)}}">{{page}}</a>
<a class="generate" href="{{url_for('generate.block', slug=page)}}">{{page}}</a>
</li>
{%endfor%}
<li>
<a href="{{url_for('generate.blocks')}}">All of them</a>
</li>
</ul>
</ol>
</body>
</html>

@ -5,30 +5,65 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Post it</title>
<link rel="stylesheet" href="{{url_for('static', filename='css/global.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/postit.css')}}" />
<link rel="stylesheet" href="{{url_for('static', filename='css/contents.css')}}" />
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>
<script src="{{url_for('static', filename='js/bleed.js')}}"></script>
</head>
<style>
:root {
--color: var(--{{color}});
--background: var(--{{color}}-bg);
}
</style>
<body>
{%for contribution, contents in contributions.items()%}
{% for content in contents %}
<div class="post-it {{content['slug']}} {% if content['card'] %} leader-card {%endif%}">
{%if content['img'] %}
<img
src="{{url_for('static', filename='contents/' + content['slug'] + '/' + content['img'] )}}"
alt="{{content['description']}}"
data-image="{{url_for('static', filename='contents/' + content['slug'] + '/' + content['img'] )}}"
/>
<figcaption>{{content['description']}}</figcaption>
{%for contribution, contents in contributions.items()%} {% for content in contents %}
<!-- Parsing postit -->
<div
class="post-it {{contribution}}
{% if content['card'] %} leader-card {%endif%}"
>
<!-- post-it with pic attribute are graphics that follow the color scheme! -->
<!-- there is a version that matches the color in a folder with the name of the color -->
<!-- ex: a purple cover in the intro contribution will be something like /intro/purple/cover.jpg -->
<!-- ex: the same cover in the orange version will be in /intro/orange/cover.jpg -->
<!-- in order to make it works, the files need to share the same name! -->
{%if content['pic'] %}
<img
src="{{url_for('static', filename='contents/' + contribution + '/' + color + '/' + content['pic'] )}}"
{% if content["alt"] %}
alt="{{content['alt']}}"
{% endif %}
/>
{% if content["alt"] %}
<figcaption>{{content['alt']}}</figcaption>
{% endif %}
<!-- post-it with img attribute it's a image that doesn't follow the color scheme -->
{%elif content['img'] %}
<img
src="{{url_for('static', filename='contents/' + contribution + '/' + content['img'] )}}"
{% if content["alt"] %}
alt="{{content['alt']}}" {% endif %}
/>
{% if content["alt"]%}
<figcaption>{{content['alt']}}</figcaption>
{% endif %}
<!-- post-it with card attribute are the card for The Leader game -->
{%elif content['card']%}
<div class="card">{{content['card']}}</div>
<blockquote class="quote">{{content['quote']}} <span class="leader">The&nbsp;Leader</span></blockquote>
<blockquote class="quote">
{{content['quote']}} <span class="leader">The&nbsp;Leader</span>
</blockquote>
<dl>
<dt class="row-bg"><span>Motivation</span></dt>
<dd class="row-bg"><span>{{content['motivation']}}</span></dd>
@ -43,9 +78,15 @@
<dd><span>{{content['positivity']}}</span></dd>
</dl>
<!-- post-it with definition attribute are for the crossword game -->
<!-- we use the same template both for the definitions and the imaginary grid cells -->
<!-- for the cells the definition attribute is a space charachter, so it's invisible but present eh eh -->
<!-- templates ecology -->
{%elif content['definition']%}
<div class="info">{{content['start']}} <span class="category">{{content['category']}}</span></div>
<div class="info">
{{content['start']}} <span class="category">{{content['category']}}</span>
</div>
<p class="description {% if content['definition']|length > 200 %} long-text {%endif%}">
{{content['definition']}}
@ -59,6 +100,8 @@
></span>
</footer>
<!-- mimic colophon, with a nice code style -->
<!-- not really a reusable module sorry aha -->
{%elif content['type'] == 'mimic-colophon'%}
<div class="description">
@ -80,25 +123,29 @@
></span>
</footer>
<!-- postit with cardinal directions are for corner layout -->
<!-- you can set the contents at: -->
<!-- top left (nw) -->
<!-- top right (ne) -->
<!-- bottom left (sw) -->
<!-- bottom right (se) -->
<!-- used in the nim dialogue and in some other 1 word post-its -->
{%elif 'nw' in content or 'ne' in content or 'se' in content or 'sw' in content%}
<p class="description dialogue
{%if content['nw']%}nw{%endif%}
{%if content['ne']%}ne{%endif%}
">
{%if content['ne']%}{{content['ne']}}{%endif%}
{%if content['nw']%}{{content['nw']}}{%endif%}
<p
class="description dialogue {%if content['nw']%}nw{%endif%} {%if content['ne']%}ne{%endif%}"
>
{%if content['ne']%}{{content['ne']}}{%endif%} {%if
content['nw']%}{{content['nw']}}{%endif%}
</p>
<p class="description dialogue
{%if content['sw']%}sw{%endif%}
{%if content['se']%}se{%endif%}
">
{%if content['se']%}{{content['se']}}{%endif%}
{%if content['sw']%}{{content['sw']}}{%endif%}
<p
class="description dialogue {%if content['sw']%}sw{%endif%} {%if content['se']%}se{%endif%}"
>
{%if content['se']%}{{content['se']}}{%endif%} {%if
content['sw']%}{{content['sw']}}{%endif%}
</p>
<footer>
<h2 class="title">{{content['title']}}</h2>
<span
@ -107,8 +154,9 @@
></span>
</footer>
{%else%}
<!-- standard text postit -->
{%else%}
<p class="description {% if content['description']|length > 200 %} long-text {%endif%}">
{{content['description']}}
@ -123,7 +171,7 @@
</footer>
{%endif%}
</div>
{% endfor %}
{%endfor%}
{% endfor %}
{%endfor%}
</body>
</html>

Loading…
Cancel
Save