Compare commits

..

No commits in common. "554ceaf5be660be226218ec7581766c329a14672" and "59c116f1d1d4018292be6626ffb04d31f4e07f38" have entirely different histories.

3 changed files with 196 additions and 216 deletions

203
build.py
View file

@ -12,13 +12,13 @@ def run(*args):
def main(): def main():
time = datetime.datetime.now() time = datetime.datetime.now()
time_id = time.strftime("%Y%m%d%H%M%S") time_id = time.strftime('%Y%m%d%H%M%S')
style = "css" style = 'css'
script = "js" script = 'js'
root = os.path.dirname(os.path.realpath(__file__)) root = os.path.dirname(os.path.realpath(__file__))
input_directory = os.path.join(root, "in") input_directory = os.path.join(root, 'in')
out = os.path.join(root, "out") out = os.path.join(root, 'out')
web = os.path.join(out, "web") web = os.path.join(out, 'web')
if os.path.exists(web): if os.path.exists(web):
shutil.rmtree(web) shutil.rmtree(web)
os.makedirs(web) os.makedirs(web)
@ -26,17 +26,17 @@ def main():
css = os.path.join(gen, style) css = os.path.join(gen, style)
js = os.path.join(gen, script) js = os.path.join(gen, script)
# #
run("rsync", "--archive", f"{input_directory}/", f"{web}/") run('rsync', '--archive', f'{input_directory}/', f'{web}/')
for directory in [css, js]: for directory in [css, js]:
os.makedirs(directory) os.makedirs(directory)
# #
link_gv = os.path.join(root, "link.gv") link_gv = os.path.join(root, 'link.gv')
link_svg = os.path.join(gen, "link.svg") link_svg = os.path.join(gen, 'link.svg')
run("dot", link_gv, "-Tsvg", "-o", link_svg) run('dot', link_gv, '-Tsvg', '-o', link_svg)
with open(link_svg, "br") as f: with open(link_svg, 'br') as f:
link_text = f.read().decode("u8") link_text = f.read().decode('u8')
page_file = os.path.join(web, "index.html") page_file = os.path.join(web, 'index.html')
page_text = f"""\ page_text = f'''\
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -195,9 +195,9 @@ Last update: {time.strftime('%Y/%m/%d %H:%M:%S')}
</body> </body>
</html> </html>
""" '''
css_file = os.path.join(css, "index.css") css_file = os.path.join(css, 'index.css')
css_text = """\ css_text = f'''\
@media screen and (max-aspect-ratio: 10/16) {{ @media screen and (max-aspect-ratio: 10/16) {{
body {{ body {{
@ -327,9 +327,9 @@ border-color: rgb(255,0,255);
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
}} }}
""" '''
js_file = os.path.join(js, "index.js") js_file = os.path.join(js, 'index.js')
js_text = """\ js_text = f'''\
function check(tab) {{ function check(tab) {{
const tabs = tab.split('/') const tabs = tab.split('/')
let id = 'tab' let id = 'tab'
@ -376,23 +376,23 @@ function main() {{
function swap() {{ function swap() {{
document.body.classList.toggle('dark') document.body.classList.toggle('dark')
}} }}
""" '''
# {link_text} # {link_text}
with open(page_file, "bw") as f: with open(page_file, 'bw') as f:
f.write(page_text.encode("u8")) f.write(page_text.encode('u8'))
with open(css_file, "bw") as f: with open(css_file, 'bw') as f:
f.write(css_text.encode("u8")) f.write(css_text.encode('u8'))
with open(js_file, "bw") as f: with open(js_file, 'bw') as f:
f.write(js_text.encode("u8")) f.write(js_text.encode('u8'))
tabs = { tabs = {
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"about": """\ 'about': f'''\
About About
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"bio": """\ 'bio': f'''\
<h1>Marc Beninca</h1> <h1>Marc Beninca</h1>
Welcome to a recap attempt of my IT life! Welcome to a recap attempt of my IT life!
@ -418,15 +418,15 @@ I had the occasion to develop projects in:
</ul> </ul>
To be continued To be continued
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"books": """\ 'books': f'''\
<ul> <ul>
<li><a href="https://www.tradepub.com">TradePub</a></li> <li><a href="https://www.tradepub.com">TradePub</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"buy": """\ 'buy': f'''\
<ul> <ul>
<li><a href="https://www.i-comparateur.com">i-comparateur</a></li> <li><a href="https://www.i-comparateur.com">i-comparateur</a></li>
</ul> </ul>
@ -451,24 +451,24 @@ To be continued…
<ul> <ul>
<li><a href="https://www.leboncoin.fr">Le bon coin</a></li> <li><a href="https://www.leboncoin.fr">Le bon coin</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"comments": """\ 'comments': f'''\
<ul> <ul>
<li><a href="https://www.youtube.com/@LogicallyAnswered/videos">Logically Answered</a></li> <li><a href="https://www.youtube.com/@LogicallyAnswered/videos">Logically Answered</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"cv": """\ 'cv': f'''\
<ul class="cards"> <ul class="cards">
<li class="card"><a href="pdf/cv.en.pdf"> <li class="card"><a href="pdf/cv.en.pdf">
<img src="img/en.svg" /><br />English</a></li> <img src="img/en.svg" /><br />English</a></li>
<li class="card"><a href="pdf/cv.fr.pdf"> <li class="card"><a href="pdf/cv.fr.pdf">
<img src="img/fr.svg" /><br />Français</a></li> <img src="img/fr.svg" /><br />Français</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"repos": """\ 'repos': f'''\
<ul> <ul>
<li><a href="https://forge.rwx.work/marc.beninca">RWX</a></li> <li><a href="https://forge.rwx.work/marc.beninca">RWX</a></li>
</ul><ul> </ul><ul>
@ -509,9 +509,9 @@ To be continued…
<ul> <ul>
<li>Gforge</li> <li>Gforge</li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"health": """\ 'health': f'''\
<ul> <ul>
<li><a href="https://www.youtube.com/@chubbyemu/videos">Chubby Emu</a></li> <li><a href="https://www.youtube.com/@chubbyemu/videos">Chubby Emu</a></li>
<li><a href="https://www.youtube.com/@drekberg/videos">Sten Ekberg</a></li> <li><a href="https://www.youtube.com/@drekberg/videos">Sten Ekberg</a></li>
@ -524,9 +524,9 @@ To be continued…
<ul> <ul>
<li><a href="https://www.youtube.com/@ivredevie/videos">Ivre de vie</a></li> <li><a href="https://www.youtube.com/@ivredevie/videos">Ivre de vie</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"id": """\ 'id': f'''\
<table> <table>
<tr><th colspan="2">OpenPGP</th><td colspan="3" rowspan="4"><img src="img/marc.jpeg" /></td></tr> <tr><th colspan="2">OpenPGP</th><td colspan="3" rowspan="4"><img src="img/marc.jpeg" /></td></tr>
@ -549,7 +549,7 @@ To be continued…
<td colspan="3"><a href="https://devs.live/users/marc_beninca">Pleroma</a></td> <td colspan="3"><a href="https://devs.live/users/marc_beninca">Pleroma</a></td>
<td><a href="https://vimeo.com/marcbeninca">Vimeo</a></td> <td><a href="https://vimeo.com/marcbeninca">Vimeo</a></td>
</tr><tr> </tr><tr>
<td colspan="2"><a href="https://videos.trom.tf/@marc_beninca">PeerTube</a></td> <td colspan="2"><a href="https://peertube.iriseden.eu/a/marc_beninca">PeerTube</a></td>
<td><a href="https://openstreetmap.org/user/Marc Beninca">OpenStreetMap</a></td> <td><a href="https://openstreetmap.org/user/Marc Beninca">OpenStreetMap</a></td>
<td><a href="https://youtube.com/@marc.beninca">YouTube</a></td> <td><a href="https://youtube.com/@marc.beninca">YouTube</a></td>
</tr><tr> </tr><tr>
@ -579,9 +579,9 @@ To be continued…
<tr><td colspan="2"><a href="https://forge.rwx.work/marc.beninca">forge.rwx.work</a></td></tr> <tr><td colspan="2"><a href="https://forge.rwx.work/marc.beninca">forge.rwx.work</a></td></tr>
</table> </table>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"learn": """\ 'learn': f'''\
<ul> <ul>
<li><a href="https://roadmap.sh">Roadmap</a></li> <li><a href="https://roadmap.sh">Roadmap</a></li>
<li><a href="https://teachyourselfcs.com">Teach Yourself Computer Science</a></li> <li><a href="https://teachyourselfcs.com">Teach Yourself Computer Science</a></li>
@ -597,9 +597,9 @@ To be continued…
<ul> <ul>
<li><a href="https://overthewire.org">Over The Wire</a></li> <li><a href="https://overthewire.org">Over The Wire</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"links": """\ 'links': f'''\
<ul> <ul>
<li><a href="https://marc-beninca.8b.io">8bio</a></li> <li><a href="https://marc-beninca.8b.io">8bio</a></li>
<li><a href="https://allmylinks.com/marc-beninca">AllMyLinks</a></li> <li><a href="https://allmylinks.com/marc-beninca">AllMyLinks</a></li>
@ -639,9 +639,9 @@ To be continued…
<li><a href="https://vu.fr/marc-beninca">Vu.Fr</a></li> <li><a href="https://vu.fr/marc-beninca">Vu.Fr</a></li>
<li><a href="https://zaap.bio/marc.beninca">Zaap</a></li> <li><a href="https://zaap.bio/marc.beninca">Zaap</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"music": """\ 'music': f'''\
<ul> <ul>
<li><a href="https://www.youtube.com/watch?v=_ITiwPMUzho">3 AM Coding Session</a></li> <li><a href="https://www.youtube.com/watch?v=_ITiwPMUzho">3 AM Coding Session</a></li>
</ul> </ul>
@ -666,9 +666,9 @@ To be continued…
<ul> <ul>
<li><a href="http://radio.garden/visit/pessac">Radio Garden</a></li> <li><a href="http://radio.garden/visit/pessac">Radio Garden</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"profiles": """\ 'profiles': f'''\
<ul class="cards"> <ul class="cards">
<li class="card"><a href="https://forge.rwx.work/marc.beninca"> <li class="card"><a href="https://forge.rwx.work/marc.beninca">
<img src="img/ForgeJo.svg" /><br />ForgeJo</a></li> <img src="img/ForgeJo.svg" /><br />ForgeJo</a></li>
@ -679,7 +679,7 @@ To be continued…
</ul> </ul>
<hr /> <hr />
<ul class="cards"> <ul class="cards">
<li class="card"><a href="https://videos.trom.tf/@marc.beninca"> <li class="card"><a href="https://peertube.iriseden.eu/c/marc.beninca">
<img src="img/PeerTube.png" /><br />PeerTube</a></li> <img src="img/PeerTube.png" /><br />PeerTube</a></li>
<li class="card"><a href="https://pixelfed.social/marc.beninca"> <li class="card"><a href="https://pixelfed.social/marc.beninca">
<img src="img/PixelFed.svg" /><br />PixelFed</a></li> <img src="img/PixelFed.svg" /><br />PixelFed</a></li>
@ -693,9 +693,9 @@ To be continued…
<li class="card"><a href="https://instagram.com/marc.beninca"> <li class="card"><a href="https://instagram.com/marc.beninca">
<img src="img/InstaGram.png" /><br />InstaGram</a></li> <img src="img/InstaGram.png" /><br />InstaGram</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"lsgm": """\ 'lsgm': f'''\
<h1>Live Scan Grub Menu</h1> <h1>Live Scan Grub Menu</h1>
Setup a whole EFI System Partition: Setup a whole EFI System Partition:
<ul> <ul>
@ -708,8 +708,8 @@ BASH experimenting:
<ul> <ul>
<li><a href="https://youtu.be/mx2lhm7qClc">2023/05/04: 1st boot into QCOW storage with encrypted data partition</a></li> <li><a href="https://youtu.be/mx2lhm7qClc">2023/05/04: 1st boot into QCOW storage with encrypted data partition</a></li>
</ul> </ul>
""", ''',
"ofsp": """\ 'ofsp': f'''\
<h1>Operating File System Profile</h1> <h1>Operating File System Profile</h1>
Build from mirror a full operating system bootable file image: Build from mirror a full operating system bootable file image:
<ul> <ul>
@ -730,9 +730,9 @@ BASH experimenting:
<li><a href="https://youtu.be/YhoY2gisXg4">2023/06/20: Graphical User Interface too</a></li> <li><a href="https://youtu.be/YhoY2gisXg4">2023/06/20: Graphical User Interface too</a></li>
<li><a href="https://youtu.be/PSHswxc9oU8">2023/06/13: Textual User Interface only</a></li> <li><a href="https://youtu.be/PSHswxc9oU8">2023/06/13: Textual User Interface only</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"social": """\ 'social': f'''\
<ul> <ul>
<li><a href="https://calckey.org">Calckey</a></li> <li><a href="https://calckey.org">Calckey</a></li>
<li><a href="https://joinmastodon.org">Mastodon</a></li> <li><a href="https://joinmastodon.org">Mastodon</a></li>
@ -759,9 +759,9 @@ BASH experimenting:
<ul> <ul>
<li><a href="https://nextdoor.com">NextDoor</a></li> <li><a href="https://nextdoor.com">NextDoor</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"software": """\ 'software': f'''\
<ul> <ul>
<li><a href="https://developer.puri.sm/Librem5">Librem 5</a></li> <li><a href="https://developer.puri.sm/Librem5">Librem 5</a></li>
</ul> </ul>
@ -783,16 +783,16 @@ BASH experimenting:
<li><a href="https://www.talos.dev">Talos Linux</a></li> <li><a href="https://www.talos.dev">Talos Linux</a></li>
<li><a href="https://www.endlessos.org/os">Endless OS</a></li> <li><a href="https://www.endlessos.org/os">Endless OS</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"style": """\ 'style': f'''\
<ul> <ul>
<li><input type="checkbox" id="dark" onclick="swap()">Dark</input></li> <li><input type="checkbox" id="dark" onclick="swap()">Dark</input></li>
<li><input type="checkbox" id="debug" onclick="debug()">Debug</input></li> <li><input type="checkbox" id="debug" onclick="debug()">Debug</input></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"tasks": """\ 'tasks': f'''\
<ul> <ul>
<li>categorize music</li> <li>categorize music</li>
</ul> </ul>
@ -805,9 +805,9 @@ BASH experimenting:
<ul> <ul>
<li>implement search</li> <li>implement search</li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"tbm": """\ 'tbm': f'''\
<ul class="cards"> <ul class="cards">
<li class="card"><a href="https://montempsreel.infotbm.com/arret/1224">Bertin B</a></li> <li class="card"><a href="https://montempsreel.infotbm.com/arret/1224">Bertin B</a></li>
<li class="card"><a href="https://montempsreel.infotbm.com/arret/7">Bertin V</a></li> <li class="card"><a href="https://montempsreel.infotbm.com/arret/7">Bertin V</a></li>
@ -816,9 +816,9 @@ BASH experimenting:
<li class="card"><a href="https://montempsreel.infotbm.com/arret/7802">Médiathèque V</a></li> <li class="card"><a href="https://montempsreel.infotbm.com/arret/7802">Médiathèque V</a></li>
<li class="card"><a href="https://montempsreel.infotbm.com/arret/371">Peixotto V</a></li> <li class="card"><a href="https://montempsreel.infotbm.com/arret/371">Peixotto V</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"trips": """\ 'trips': f'''\
<ul> <ul>
<li>Belgium<ul> <li>Belgium<ul>
<li>Brussels</li> <li>Brussels</li>
@ -860,9 +860,9 @@ BASH experimenting:
<li>Tennessee</li> <li>Tennessee</li>
</ul></li> </ul></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"vegan": """\ 'vegan': f'''\
<ul> <ul>
<li><a href="https://www.youtube.com/@CheapLazyVegan/videos">Cheap Lazy Vegan</a></li> <li><a href="https://www.youtube.com/@CheapLazyVegan/videos">Cheap Lazy Vegan</a></li>
<li><a href="https://www.youtube.com/@gazoakleychef/videos">Gaz Oakley</a></li> <li><a href="https://www.youtube.com/@gazoakleychef/videos">Gaz Oakley</a></li>
@ -886,9 +886,9 @@ BASH experimenting:
<li><a href="https://www.youtube.com/@MarieSweetandSour/videos">Marie Sweet and Sour</a></li> <li><a href="https://www.youtube.com/@MarieSweetandSour/videos">Marie Sweet and Sour</a></li>
<li><a href="https://www.youtube.com/@SebastienKardinal/videos">Sébastien Kardinal</a></li> <li><a href="https://www.youtube.com/@SebastienKardinal/videos">Sébastien Kardinal</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"others": """\ 'others': f'''\
<ul> <ul>
<li><a href="https://bsky.app/profile/marc-beninca.bsky.social">Blue Sky</a></li> <li><a href="https://bsky.app/profile/marc-beninca.bsky.social">Blue Sky</a></li>
<li><a href="https://buymeacoffee.com/marc.beninca">Buy Me A Coffee</a></li> <li><a href="https://buymeacoffee.com/marc.beninca">Buy Me A Coffee</a></li>
@ -902,6 +902,7 @@ BASH experimenting:
<li><a href="https://minds.com/marc_beninca">Minds</a></li> <li><a href="https://minds.com/marc_beninca">Minds</a></li>
<li><a href="https://odysee.com/@marc.beninca">Odysee</a></li> <li><a href="https://odysee.com/@marc.beninca">Odysee</a></li>
<li><a href="https://paypal.me/MarcBeninca">PayPal</a></li> <li><a href="https://paypal.me/MarcBeninca">PayPal</a></li>
<li><a href="https://peertube.iriseden.eu/a/marc_beninca">PeerTube</a></li>
<li><a href="https://pinterest.com/marc_beninca">Pinterest</a></li> <li><a href="https://pinterest.com/marc_beninca">Pinterest</a></li>
<li><a href="https://marcbeninca.podia.com">Podia</a></li> <li><a href="https://marcbeninca.podia.com">Podia</a></li>
<li><a href="https://app.revolt.chat/invite/01FREKCG3P2P0YMAHQSCPSW4GD">Revolt</a></li> <li><a href="https://app.revolt.chat/invite/01FREKCG3P2P0YMAHQSCPSW4GD">Revolt</a></li>
@ -917,15 +918,15 @@ BASH experimenting:
<ul> <ul>
<li><a href="">KissBank</a></li> <li><a href="">KissBank</a></li>
</ul> </ul>
""", ''',
# ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ #⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
"unsorted": """\ 'unsorted': f'''\
<ul> <ul>
<li><a href="https://foss.events">FOSS Events</a></li> <li><a href="https://foss.events">FOSS Events</a></li>
</ul> </ul>
""", ''',
} }
if __name__ == "__main__": if __name__ == '__main__':
main() main()

View file

@ -1,83 +1,61 @@
from __future__ import annotations
import os import os
from pathlib import Path
import subprocess import subprocess
PORT = 22 PORT = 22
USER = "mspe" USER = 'mspe'
ROOT = "public_html" ROOT = 'public_html'
PROTOCOL = "https" PROTOCOL = 'https'
DIR = False DIR = False
class PubNix: class PubNix:
def __init__(
self, def __init__(self, dn,
dn, ssh=None, port=PORT, user=USER,
ssh: str | None = None, root=ROOT, dir=DIR, web=None, sub=None):
port: int = PORT,
user: str = USER,
root: str = ROOT,
dir: bool = DIR,
web: str | None = None,
sub: bool | None = None,
):
self.dn = dn self.dn = dn
self.ssh = f"{ssh}.{self.dn}" if ssh else self.dn self.ssh = f'{ssh}.{self.dn}' if ssh else self.dn
self.port = port self.port = port
self.user = user self.user = user
self.root = root self.root = root
self.web = f"{web}.{self.dn}" if web else self.dn self.web = f'{web}.{self.dn}' if web else self.dn
if sub: if sub:
self.fqdn = f"{self.user}.{self.web}" self.fqdn = f'{self.user}.{self.web}'
self.context = None self.context = None
else: else:
self.fqdn = self.web self.fqdn = self.web
self.context = f"~{self.user}" self.context = f'~{self.user}'
self.path = (Path(self.root) / self.fqdn) if dir else self.root self.path = os.path.join(self.root, self.fqdn) if dir else self.root
self.target = f"{self.user}@{self.ssh}:{self.path}" self.target = f'{self.user}@{self.ssh}:{self.path}'
self.url = [f"{PROTOCOL}:", "", self.fqdn] self.url = [f'{PROTOCOL}:', str(), self.fqdn]
if self.context: if self.context:
self.url.append(self.context) self.url.append(self.context)
self.url = "/".join(self.url) self.url = '/'.join(self.url)
def capturun(self, *args): def capturun(self, *args):
return self.run(*args, capture_output=True) return self.run(*args, capture_output=True)
def run(self, *args, **kwargs): def run(self, *args, **kwargs):
return subprocess.run( return subprocess.run(['ssh',
[ '-o', 'LogLevel Error',
"ssh", '-p', str(self.port),
"-o", f'{self.user}@{self.ssh}',
"LogLevel Error", '--',
"-p",
str(self.port),
f"{self.user}@{self.ssh}",
"--",
*args, *args,
], ], **kwargs)
**kwargs,
)
def disk_free(self) -> str: def disk_free(self):
"""Fetch free space information.""" process = self.capturun('df', '-h', os.curdir)
process = self.capturun("df", "-h", os.curdir) return process.stdout.decode('UTF-8').strip()
return process.stdout.decode("UTF-8").strip()
def os(self) -> str: def os(self):
"""Fetch Operating System release information.""" ps = self.capturun('cat', '/etc/os-release')
ps = self.capturun("cat", "/etc/os-release")
if ps.returncode == 0: if ps.returncode == 0:
for line in ps.stdout.decode("UTF-8").strip().split(os.linesep): for line in ps.stdout.decode('UTF-8').strip().split(os.linesep):
if "PRETTY_NAME" in line: if 'PRETTY_NAME' in line:
text = line.split("=")[1].split('"')[1] return line.split('=')[1].split('"')[1]
break
else: else:
text = "" return self.capturun('uname', '-sr').stdout.decode('UTF-8').strip()
return text
else:
return self.capturun("uname", "-sr").stdout.decode("UTF-8").strip()
def __str__(self) -> str: def __str__(self):
"""Return target & url."""
return os.linesep.join([self.target, self.url]) return os.linesep.join([self.target, self.url])

119
sync.py
View file

@ -1,78 +1,79 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
"""Synchronize to remote pubnixes."""
from __future__ import annotations import os
from logging import log
from os import sep
from pathlib import Path
from pubnix import PubNix
import subprocess import subprocess
import pubnix
ARGS = [ ARGS = [
{ {'dn':'blinkenshell.org',
"dn": "blinkenshell.org", 'ssh': 'ssh', 'port': 2222, 'web': 'u', 'sub': True},
"ssh": "ssh", {'dn':'ctrl-c.club', 'sub': False},
"port": 2222, {'dn':'dimension.sh', 'sub': True},
"web": "u", {'dn':'envs.net', 'sub': True},
"sub": True, {'dn':'freeshell.de', 'sub': False},
}, # {'dn':'hextilde.xyz', 'sub': True},
{"dn": "ctrl-c.club", "sub": False}, {'dn':'insomnia247.nl', 'dir': True, 'sub': True},
{"dn": "dimension.sh", "sub": True}, {'dn':'p.projectsegfau.lt', 'sub': True},
{"dn": "envs.net", "sub": True}, # {'dn':'pubnix.pink', 'web': 'sites', 'sub': False},
{"dn": "freeshell.de", "sub": False}, {'dn':'rawtext.club', 'sub': False},
{"dn": "insomnia247.nl", "dir": True, "sub": True}, {'dn':'rw.rs', 'sub': False},
{"dn": "p.projectsegfau.lt", "sub": True}, {'dn':'thunix.net', 'sub': False},
{"dn": "rawtext.club", "sub": False}, {'dn':'tilde.32bit.cafe', 'root': 'www', 'sub': False},
{"dn": "rw.rs", "sub": False}, {'dn':'tilde.cafe', 'sub': True},
{"dn": "thunix.net", "sub": False}, {'dn':'tilde.club', 'sub': False},
{"dn": "tilde.32bit.cafe", "root": "www", "sub": False}, {'dn':'tilde.fun', 'root': 'html', 'sub': False},
{"dn": "tilde.cafe", "sub": True}, {'dn':'tilde.green', 'sub': False},
{"dn": "tilde.club", "sub": False}, {'dn':'tilde.guru', 'sub': False},
{"dn": "tilde.fun", "root": "html", "sub": False}, {'dn':'tilde.institute', 'sub': True},
{"dn": "tilde.green", "sub": False}, {'dn':'tilde.pink', 'sub': False},
{"dn": "tilde.guru", "sub": False}, {'dn':'tilde.team', 'sub': True},
{"dn": "tilde.institute", "sub": True}, {'dn':'tilde.town', 'sub': False},
{"dn": "tilde.pink", "sub": False}, # {'dn':'trash.town', 'sub': False},
{"dn": "tilde.team", "sub": True}, # permissions
{"dn": "tilde.town", "sub": False}, # {'dn':'sdf.org', 'root': 'html', 'sub': True},
# old # old
{"dn": "fr.tild3.org", "sub": True}, {'dn':'fr.tild3.org', 'sub': True},
{"dn": "remotes.club", "port": 9022, "root": "web", "sub": True}, {'dn':'remotes.club', 'port': 9022, 'root': 'web', 'sub': True},
{"dn": "squiggle.city", "sub": False}, {'dn':'squiggle.city', 'sub': False},
# down
# {'dn':'aussies.space', 'sub': False},
# {'dn':'heathens.club', 'root': 'www', 'sub': False},
# {'dn':'vern.cc', 'sub': True},
] ]
PUBNIXES = [PubNix(**args) for args in ARGS] PUBNIXES = [pubnix.PubNix(**args) for args in ARGS]
def sync(root: Path, pubnix: PubNix, exclude: list[str] | None = None) -> None: def sync(root, pubnix, exclude=None):
"""Synchronize local root directory with pubnix."""
args = [ args = [
"rsync", 'rsync',
"--archive", '--archive',
"--checksum", '--checksum',
"--delete-before", '--delete-before',
"--rsh", '--rsh', f"ssh -o 'LogLevel Error' -p {pubnix.port}",
f"ssh -o 'LogLevel Error' -p {pubnix.port}", '--partial',
"--partial", '--progress',
"--progress", '--verbose',
"--verbose", os.path.join(root, str()),
f"{root}{sep}",
] ]
if exclude:
for item in exclude: for item in exclude:
args.extend(["--exclude", f"{sep}{item}"]) args.extend(['--exclude', os.path.join(str(), item)])
args.append(f"{pubnix.target}{sep}") args.append(os.path.join(pubnix.target, str()))
subprocess.call(args, stdout=subprocess.DEVNULL) subprocess.call(args, stdout=subprocess.DEVNULL)
def main() -> None: def main():
"""Synchronize content on remote pubnixes.""" root = os.path.dirname(os.path.realpath(__file__))
root = Path(__file__).resolve().parent / "out" / "web" root = os.path.join(root, 'out', 'web')
for pn in PUBNIXES: dns_length = max([len(pubnix.dn) for pubnix in PUBNIXES])
log() for pubnix in PUBNIXES:
log(pn) print()
sync(root, pn, exclude=["__pycache__", "pgp.asc"]) print(pubnix)
# print(f'{pubnix.dn.rjust(dns_length)} → ', end=str(), flush=True)
sync(root, pubnix, exclude=['__pycache__', 'pgp.asc'])
# print(pubnix.disk_free())
# print(pubnix.os())
if __name__ == "__main__": if __name__ == '__main__':
main() main()