Compare commits

...

8 Commits

17 changed files with 307 additions and 116 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ __pycache__/
static/*
public_*/*
packagescript
racredentials.py

View File

@ -8,11 +8,12 @@ I made some slight changes to better suit my needs:
- Edits to the CSS file to ease the change of color scheme
- Better handling of header levels
- Auto-filling the author and blog names on most of the files
- RetroAchievements integration (optional, for now only generates a page of mastered/beaten games)
Key features made by Ploum:
- Support for blog posts in French and English
- Generate HTML and Gemini files
- RSS/Atom feed
- RSS/Atom feeds
For more information, see the original repo : https://sr.ht/~lioploum/ploum.net/
@ -22,4 +23,4 @@ I will only maintain this for my personal use, I most probably won't accept PR o
## License
The generator is aGPLv3 licensed. My website's content (everything in the [en/] and [fr/] folders) is CC0.
The generator is aGPLv3 licensed. My website's content (everything in the [en/], [fr/] and [rareview/] folders) is CC0.

7
default_rareview.gmi Normal file
View File

@ -0,0 +1,7 @@
# $AWARDNAME
Award got on the $AWARDDATE
=> $AWARDGAMEURL View this game on RetroAchievements
No review written yet, come back later!

68
en/about.gmi Normal file
View File

@ -0,0 +1,68 @@
# About
## Ways to subscribe
=> atom.xml Flux RSS complet
=> atom_fr.xml Flux RSS, en français seulement
=> atom_en.xml RSS feed, in English only
=> atom_rareview.xml RSS feed, only RetroAchievements reviews
## Contact
=> /contact.gmi Contact page
## En français (English at the bottom)
### À propos de moi
Salut! Moi c'est Théo (il/iel), j'étudie l'informatique à l'Université de Strasbourg!
Affectif et fatigué, je suis un grand fan de jeux vidéos (principalement rétros). Mes favoris sont les jeux de plateforme. Je programme aussi quand j'en trouve la motivation.
Pendant mon temps libre, je m'intéresse aussi à la cuisine, à la philosophie, à l'éthique, et à la sociologie. À la croisée de ces intérêts se trouve mon régime végétarien.
### À propos de ce site
Ce site fait parti d'un webring, le fediring, rassemblant diverses sites (souvent anglophones) dont les auteur.e.s ont une présence sur le fédiverse.
=> https://fediring.net/ Le site du fediring
Généré à partir du même générateur que Ploum.net (même si légèrement modifié), un grand merci à ellui pour avoir laissé ses sources en libre accès!
=> https://ploum.net/ Le site de Ploum
Mon site est hébergé chez sourcehut, est généré statiquement, et ne comporte pas de JavaScript.
=> https://sr.ht/ Le site de sourcehut
## In English (en Français plus haut)
### A bit about me
Hi! I'm Théo (he/they), studying computer science at Strasbourg's university (in France)!
I'm an always cuddly, often tired, video game fan (I mainly play retro ones these days). My favorites are platformer games. I'm also programming sometimes.
I'm also interested in cooking, philosophy, ethics, and sociology. I try not to cause suffering, notably trough what I'm eating.
### About this site
This site is part of a webring, the fediring, composed of other great sites. The point of this one is to link people that have a presence on the fediverse.
=> https://fediring.net/ Fediring's website
This site use the same generator (with some modifications) as Ploum's one. Huge thanks to them for making it!
=> https://ploum.net/ Ploum's site
My site is currently hosted at SourceHut's.
=> https://sr.ht/ SourceHut's site
## Misc
I also made a 88x31 button for this site!
You can integrate it in your site with the following code :
```
<a href='https://webair.xyz'><img src='https://webair.xyz/img/button.png' width=88 height=31></a>
```
=> /img/button.png The 88x31 button, showing the website's name with some hearts

23
en/contact.gmi Normal file
View File

@ -0,0 +1,23 @@
# How to contact me
## General
=> mailto:theow@tutanota.de Mail
=> https://soc.webair.xyz/@theo Mastodon/Fediverse
=> https://matrix.to/#/@theo:mtrx.webair.xyz Matrix
=> https://matrix.to/#/@theo:catgirl.cloud Matrix (backup)
## Games
=> https://steamcommunity.com/id/ayteonsteam/ Steam
=> https://retroachievements.org/user/ayte RetroAchievements
=> https://justayte.itch.io Itch.io
## Software
=> https://forge.chapril.org/ayte/ Gitea
## GPG
```
$GPGPUBKEY
```

View File

@ -1,6 +1,7 @@
# $GLOBAL_TITLE
Hi, I'm Alice, a computer science student from the Strasbourg's university (in France). I'm interested in philosophy, cooking, video games, and tinkering with software !
Hi, I'm Theo, a computer science student from the Strasbourg's university (in France). I'm interested in philosophy, cooking, video games, and tinkering with software!
=> software.gmi Projects I worked on
=> about.gmi For more information on me and this site
=> /software.gmi Projects I worked on
=> /about.gmi For more information on me and this site
=> /contact.gmi For all my online profiles

View File

@ -1,95 +0,0 @@
# About
## Ways to subscribe
=> atom.xml Flux RSS complet
=> atom_fr.xml Flux RSS, en français seulement
=> atom_en.xml RSS feed, in English only
=> https://soc.webair.xyz/@theo Fediverse: @theo@soc.webair.xyz
## En français (English at the bottom)
### À propos de moi
Salut ! Moi c'est Alice, une étudiante en informatique à l'Université de Strasbourg ! J'ai pas mal de noms, tu peux m'appeller de différentes manières:
- Théo, avec des pronoms neutres ou masculins
- Alice, avec des pronoms neutres ou féminins
J'ai également quelques pseudos, que j'utilise exclusivement sur internet ou sur des jeux, comme "ayte", "0x2B" ou "famine".
Au final appelles moi comme tu veux, je suis à l'aise avec tout les pronoms.
Toujours affective, souvent fatiguée, je suis une grande fan de jeux vidéos (principalement rétros). Mes favoris sont les jeux de plateforme, style Celeste, Super Meat Boy, 1001 Spikes, ou autres. J'ai eu la chance de grandir avec une GameBoy Color dans les mains, et une GameCube dans le salon. Je programme aussi quand j'en trouve la motivation, en python, en C, ou en Zig.
Pendant mon temps libre, je m'intéresse aussi à la cuisine, à la philosophie, à l'éthique, et à la sociologie. À la croisée de ces intérêts se trouve mon régime végétarien. Il y a tellement de choses à découvrir, à changer, à faire, que cela me fige parfois.
### À propos de ce site
#### Le contenu
Ce que j'écris ici est avant tout destiné à mon moi du futur, n'implique donc que moi, et n'est pas professionnel.
Au lieu de me répéter si je dois expliquer quelque chose à des moments différents, j'écris. En formalisant un peu mes idées, j'existe un peu plus aux yeux des autres, mais surtout à mes propres yeux, cela me permet de me faire une mise au point.
Ce site fait parti d'un webring, le fediring, rassemblant diverses sites (souvent anglophones) dont les auteur.e.s ont une présence sur le fédiverse.
=> https://fediring.net/ Le site du fediring
#### D'un point de vue technique
Généré à partir du même générateur que Ploum.net (même si légèrement modifié), un grand merci à lui pour avoir laissé ses sources en libre accès !
=> https://ploum.net/ Le site de Ploum
Mon site est hébergé chez sourcehut, est généré statiquement, et ne comporte pas de JavaScript.
=> https://sr.ht/ Le site de sourcehut
## In English (en Français plus haut)
### A bit about me
Hi ! I'm Alice, studying computer science at Strasbourg's university (in France) ! I go by these names:
- Theo, usually with he/him or they/them
- Alice, with she/her or they/them
When I'm on the internet, or when I'm playing games, I usually choose one of these nicknames:
- ayte
- 0x2B
- famine
In the end, you can call me whatever you want, it does not really matter to me.
I'm an always cuddly, often tired, video game fan (I mainly play retro ones these days). My favorites are platformer games, like Celeste, Super Meat Boy, 1001 Spikes, or others. I've been lucky enough to grow up with a GameBoy Color in my hand, and a GameCube in my living room. I'm also programming sometimes, in python, C, and Zig.
I'm also interested in cooking, philosophy, ethics, and sociology. I try not to cause suffering, notably trough what I'm eating.
There's so much to discover, so much to change, so much to do, that sometimes it gets a bit scary.
### About this site
I'm mainly writing for myself and my future self, it is a personnal blog. Having my thoughts written somewhere is helpful when I need to explain the same thing at different times.
I'm writing, not to exist in the eyes of others, but to exist in my own eyes. In some way, this thing helps me being more "real" in a sense.
This site is part of a webring, the fediring, composed of other great sites. The point of this one is to link people that have a presence on the fediverse.
=> https://fediring.net/ Fediring's website
#### On the technical side
This site use the same generator (with some minor modifications) as Ploum's one. Huge thanks to them for making it !
=> https://ploum.net/ Ploum's site
My site is currently hosted at SourceHut's.
=> https://sr.ht/ SourceHut's site
## Contact
=> https://soc.webair.xyz/@theo Fediverse: @theo@soc.webair.xyz
=> https://matrix.to/#/@theo:mtrx.webair.xyz Matrix: @theo:mtrx.webair.xyz
=> mailto:theow@tutanota.de Mail: theow@tutanota.de
I also made a 88x31 button for this site !
You can integrate it in your site with the following code :
```
<a href='https://webair.xyz'><img src='https://webair.xyz/img/button.png' width=88 height=31></a>
```
=> img/button.png The 88x31 button, showing the website's name with some hearts

View File

@ -1,6 +1,7 @@
# $GLOBAL_TITLE
Salut, moi c'est Alice, étudiante en informatique à l'Université de Strasbourg. Jaime la cuisine, la philosophie, les jeux vidéos, et bidouiller des logiciels !
Salut, moi c'est Théo, j'étudie l'informatique à l'Université de Strasbourg. Jaime la cuisine, la philosophie, les jeux vidéos, et bidouiller des logiciels!
=> software.gmi Les projets auxquels je participe
=> about.gmi Pour plus d'information sur moi et ce site
=> /software.gmi Les projets auxquels je participe
=> /about.gmi Pour plus d'information sur moi et ce site
=> /contact.gmi Pour mes différents profils

View File

@ -8,6 +8,7 @@
<link href="atom.xml" type="application/atom+xml" rel="alternate" title="$GLOBAL_TITLE (all posts)" >
<link href="atom_en.xml" type="application/atom+xml" rel="alternate" title="$GLOBAL_TITLE (EN only)" >
<link href="atom_fr.xml" type="application/atom+xml" rel="alternate" title="$GLOBAL_TITLE (en français)" >
<link href="atom_rareview.xml" type="application/atom+xml" rel="alternate" title="$GLOBAL_TITLE (RetroAchievements Reviews)" >
<link rel="shortcut icon" href="img/favicon.png" >
<link rel="me" href="https://soc.webair.xyz/@theo">
<link rel="canonical" href="$HTMLLINK">
@ -36,7 +37,7 @@
line-height:1.2;
border-bottom: 1px solid;
}
blockquote,.signature{
blockquote,.signature, pre{
font-style: italic;
margin: 2em 1em;
background: var(--bg-alt);
@ -44,11 +45,6 @@
}
pre {
overflow: auto;
padding: 5px;
background-color: var(--bg-alt);
border-style: dashed;
border-width: 5px;
border-color: var(--bg);
}
.signature{
text-align: center;
@ -59,7 +55,7 @@
a {
color:var(--fg-alt);
text-decoration:none;
padding:1em 0;
border:1em 0;
}
a:hover {
text-decoration:underline;
@ -85,6 +81,7 @@
text-align: center;
font-variant: small-caps;
font-weight: bold;
padding: 1em;
}
.horizontal {
text-align: center;
@ -107,7 +104,9 @@
<div class="navbar">
<a href="/index.html">Blog</a>
<a href="/software.html">Software</a>
<a href="/about.html">À Propos</a>
<a href="/retroachievements.html">RA</a>
<a href="/about.html">About</a>
<a href="/contact.html">Contact</a>
</div>
<article>
$IMAGE_HEADER

41
public.gpg Normal file
View File

@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
o/SIa3jegj+ZqyoFNOq9VTA=
=H3IG
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -9,12 +9,22 @@ import html
from datetime import datetime
import textwrap
import unicodedata
import ra
import racredentials
global_title = "webair.xyz"
global_subtitle = "Alice's web corner"
global_name = "Alice"
global_subtitle = "Theo's web corner"
global_name = "Theo"
base_url = "webair.xyz/"
global_pubkey = ""
try:
with open("public.gpg", "r") as f:
global_pubkey = f.read()
except FileNotFoundError:
print("GPG public key not found!")
global_pubkey = ""
geminidir = "./public_gemini"
htmldir = "./public_html"
local_url = "/home/ploum/dev/gemlog/"
@ -25,6 +35,8 @@ old_post_url = ["2005-01-25","2013-05-17","2011-02-07","2012-03-19","2012-01-18"
html_page_template = "page_template.html"
email_template = "email_template.html"
gemini_page_template = "page_template.gmi"
raindex_template = "raindex_template.gmi"
raindex_destination = "rareview/retroachievements.gmi"
image_extensions = [".png", ".jpg", ".jpeg"]
@ -48,6 +60,7 @@ def fill_globals(text):
.replace("$BASE_URL", base_url)\
.replace("$GLOBAL_TITLE", global_title)\
.replace("$SUBTITLE", global_subtitle)\
.replace("$GPGPUBKEY", global_pubkey)
# Add the html version to the post dictionnary
@ -254,7 +267,7 @@ def build_list(allposts,folder,local=False):
allposts = build_list(allposts,ff,local=local)
elif f.endswith(".gmi") and "index" not in f and "template" not in f:
if len(folder) > 2:
lang = folder[:2]
lang = folder
else:
lang = "fr"
post = build_post(p,lang=lang,local=local)
@ -331,7 +344,7 @@ def build_index(allposts,folder,short=False):
index = {}
if folder:
indexname = "index_" + folder.strip("/").replace("/","_")
lang = folder[:2]
lang = folder
else:
if short:
indexname = "index"
@ -496,6 +509,43 @@ def copy_static_files(source, dest):
os.popen(f"cp -r {source}/* {dest}/")
def generate_raindex(awards, dest):
content = ""
with open(raindex_template) as f:
content = f.read()
content += "\n"
for award in reversed(awards):
content += f"=> {award.url} {award.type} {award.name}\n"
with open(dest, "w") as f:
f.write(content)
def generate_default_rareviews(awards):
for award in awards:
default_page = ""
with open("default_rareview.gmi", "r") as f:
default_page = f.read()
filepath = Path(award.url)
# Check if a file with same name doesn't exists in current folder
if not os.path.exists(filepath):
# Check if a review was not already written
if not os.path.exists(os.path.join("rareview", filepath)):
# Write a default page
with open(filepath, "w") as f:
f.write(
default_page.replace("$AWARDNAME", award.name)
.replace("$AWARDDATE", award.date)
.replace("$AWARDGAMEURL", award.gameurl)
)
# Build a post with it
post = build_post(filepath, lang="rareview")
writehtml(post)
writegmi(post)
os.remove(filepath)
else:
print(f"Warning, file {filepath} exists in root folder, skipping.")
# Main call
if __name__ == "__main__":
# Check for the destination folders
@ -504,10 +554,14 @@ if __name__ == "__main__":
os.mkdir(dir)
all_posts = []
local = False
# Generate the RetroAchievements index page
awards = ra.getAwards(racredentials.user, racredentials.key)
generate_raindex(awards, raindex_destination)
# Normal generation
if len(sys.argv) > 1:
local = sys.argv[1] == "local"
print("building locally")
for folder in ["", "fr", "en"]:
for folder in ["", "fr", "en", "rareview"]:
all_posts = build_list(all_posts, folder, local=local)
all_posts = build_index(all_posts, folder)
write_atom_index(all_posts, folder)
@ -518,4 +572,8 @@ if __name__ == "__main__":
for p in all_posts:
writehtml(p)
writegmi(p)
# Generate default RaReview pages
generate_default_rareviews(awards)
# Delete the generated raindex
os.remove(raindex_destination)
copy_static_files("static", htmldir)

70
ra.py Normal file
View File

@ -0,0 +1,70 @@
import json
import requests
from racredentials import user, key
BASE_URL = "https://retroachievements.org/API/"
WEB_URL = "https://retroachievements.org"
class Award:
def __init__(self, awarddict):
self.name = awarddict["Title"]
self.type = awarddict["AwardType"]
self.date = awarddict["AwardedAt"]
self.iconurl = WEB_URL + awarddict["ImageIcon"]
self.gameurl = WEB_URL + "/game/" + str(awarddict["AwardData"])
if awarddict["ConsoleName"] == "Events":
self.name = "~Event~ " + self.name
self.url = self.genurl()
def genurl(self):
# lower the string
name = self.name.lower()
# Only keep letters, and replace spaces
stripped = ""
for c in name.strip():
if ord("a") <= ord(c) <= ord("z"):
stripped += c
elif ord("0") <= ord(c) <= ord("9"):
stripped += c
else:
stripped += "-"
# delete multiple following dashes
splitted = stripped.split("-")
while splitted.count("") > 0:
splitted.remove("")
stripped = "-".join(splitted)
# Concatenate date
date = self.date.split("T")[0]
return f"{date}-{stripped}.gmi"
def request(path):
return json.loads(requests.get(BASE_URL + path).text)
def getAwards(user, key):
response = request(f"API_GetUserAwards.php?z={user}&y={key}&u={user}")
if "VisibleUserAwards" in response.keys():
response = response["VisibleUserAwards"]
indexed = {}
# Returns only the mastered award
# in case there's both a completed and master award
for award in [Award(x) for x in response]:
if award.name in indexed.keys():
if indexed[award.name].type == "Game Beaten":
indexed[award.name] = award
else:
indexed[award.name] = award
sorted = list(indexed.values())
sorted.sort(key=lambda x: x.date)
return sorted
else:
print(response)
return []
if __name__ == "__main__":
awards = getAwards(user, key)
for award in awards:
print(award.name, award.url)

2
racredentials.py Normal file
View File

@ -0,0 +1,2 @@
user = "REPLACE THIS"
key = "REPLACE THIS"

11
raindex_template.gmi Normal file
View File

@ -0,0 +1,11 @@
# RetroAchievements Awards
Here's a list of my most recently mastered/completed games on RetroAchievements.
=> https://retroachievements.org/user/ayte/ My profile
I wrote reviews for some of them.
=> /index_rareview.gmi All the reviews I wrote
## The full list of awards

3
rareview/signature.html Normal file
View File

@ -0,0 +1,3 @@
<p>If you can read this, then maybe you're interested in subscribing to my reviews <a href="/atom_rareview.xml">by RSS</a>.</p>
<p>You can see the full list of my RetroAchievements Awards <a href="/retroachievements.html">here</a>.</p>
<p>Thanks for your time ❤</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 679 B