:: rewrite ::
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
hexlocation 2024-10-05 00:48:55 +02:00
parent e30a136cc2
commit 775cbae281
23 changed files with 724 additions and 326 deletions

132
assets/css/global.css Normal file
View file

@ -0,0 +1,132 @@
#top {
margin-top: 2vw;
margin-left: 15vw;
margin-right: 15vw;
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
@font-face {
font-family: "Jetbrains Mono";
src: url(/assets/ttf/JBM.ttf);
}
:root {
--text-color: #8941ad;
--term-color: #4af626;
}
body {
color: var(--term-color);
background-color: black;
font-family: "Jetbrains Mono";
}
#link-container a {
text-decoration: none;
color: var(--term-color);
}
#link-container {
display: flex;
gap: 4vw;
}
hr {
margin-top: 1px;
color: var(--term-color);
}
/*
CSS styling for guestbook
*/
#entries {
align-items: center;
gap: 10px;
margin-top: 10px;
display: flex;
flex-direction: column;
}
.guest-entry {
width: 100%;
}
bu {
font-weight: bold;
text-decoration: underline;
}
.entry-header {
display: flex;
justify-content: space-between;
}
.entry-body {
font-size: 14px;
overflow: auto;
word-wrap: break-word;
}
a {
text-decoration: none;
color: var(--term-color);
}
#post-container {
text-align: center;
padding: 5px;
margin: auto;
margin-top: 10px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
flex: 0 0 auto;
}
input,
textarea {
margin-left: 5vw;
}
.break {
flex-basis: 100%;
height: 0;
}
.link:hover {
background-color: var(--term-color);
color: black;
}
label {
text-align: left;
clear: both;
float: left;
}
/*
CSS styling for services page.
*/
:root {
--sin-padding: 5px;
}
#service-containers {
display: flex;
gap: 10px;
flex-wrap: wrap;
width: 100%;
justify-content: center;
}
.service-link {
color: var(--term-color);
vertical-align: middle;
}
.service-icon {
vertical-align: middle;
}
.service-title {
align-items: center;
gap: 5px;
display: flex;
margin: 0;
justify-content: center;
}
.service-container {
padding: var(--sin-padding);
padding-top: 0px;
flex-shrink: 0;
border: 1px solid var(--term-color);
flex-basis: 22%;
}
.service-container hr {
margin-left: calc(-1 * var(--sin-padding));
margin-right: calc(-1 * var(--sin-padding));
}

BIN
assets/img/authelia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
assets/img/dn42.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
assets/img/jellyfin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

BIN
assets/img/jellyseerr.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

BIN
assets/img/mail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

10
assets/img/woodpecker.svg Normal file
View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="284.538" height="253.96">
<style>
@media (prefers-color-scheme: dark) {
path {
fill: white;
}
}
</style>
<path d="M162.51 33.188c-26.77.411-54.004 6.885-71.494 3.745-1.313-.232-2.124 1.338-1.171 2.265 14.749 14.003 20.335 28.16 36.718 30.065l.476.103c-7.567 7.799-14.028 18.018-18.571 31.171-4.89 14.106-6.268 29.421-7.89 47.105-2.445 26.332-5.173 56.152-20.038 93.54a246.489 246.489 0 0 0-13.27 45.946h22.652a221.202 221.202 0 0 1 11.249-37.786c16.049-40.374 19.073-73.257 21.505-99.693 1.493-16.255 2.806-30.309 6.796-41.853 11.647-33.527 39.408-40.889 61.056-36.693 21.004 4.067 41.673 20.502 40.592 44.016-.772 15.985-7.76 23.166-12.87 28.43-2.793 2.883-5.47 5.611-6.731 9.498-3.037 9.19.101 19.434 8.494 27.568 22.24 20.734 34.338 59.717 33.681 106.513h22.176c.592-52.935-13.951-97.839-40.503-122.626-2.097-2.021-2.69-3.604-3.191-3.347 1.222-1.544 3.217-3.346 4.633-4.813 29.382-21.79 77.813-1.892 107.054 9.653 7.58 2.985 11.274-4.338 4.067-8.623-25.097-14.84-76.54-54.016-105.368-79.718-4.029-3.54-6.796-7.8-11.455-11.738-15.547-27.439-41.84-33.127-68.597-32.728Zm35.238 60.27a15.161 15.161 0 0 0-2.008.232 15.161 15.161 0 0 0-1.506 29.434 15.154 15.154 0 0 0 9.473-28.79 15.161 15.161 0 0 0-5.959-.876zm-44.286 147.17a2.033 2.033 0 0 0-1.133.374c-1.08.772-1.93 3.05-.772 5.701 5.38 12.394 9.1 25.445 12.536 40.413h22.484c-5.676-16.629-16.307-34.055-27.851-43.978-2.008-1.737-3.913-2.574-5.251-2.51z" style="stroke-width:12.8704" transform="translate(-67.27 -33.169)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
assets/pgp/andre.txt Normal file
View file

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZs80XRYJKwYBBAHaRw8BAQdAFEbr22JHklXkyOgqDp/o/IgngPN6Sck3Mjih
LLDjwTy0GEFuZHJlIDxvcGVucmNAcG9zdGVvLmRlPoiTBBMWCgA7FiEEIe1Ep7aw
ZGGQHzkyFuz+3MRZea4FAmbR+S0CGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcC
F4AACgkQFuz+3MRZea7GewD/cEexNFi6y0eZqiWduihvyrJjnD8mDKQ8W5+Nt23v
60IA/2AdbuULXtJ2wsww/3VpIjN22AJdTTZQq9SEgLbhqfwLuDgEZs80XRIKKwYB
BAGXVQEFAQEHQL53gX/5GbufLJYAcb+nAT59LCaPFXk5FgmoOZTxic49AwEIB4h4
BBgWCgAgFiEEIe1Ep7awZGGQHzkyFuz+3MRZea4FAmbPNF0CGwwACgkQFuz+3MRZ
ea754AEAkjXsfyVYCBBUHiBKF8m1aEtWx1xFwUlXXQ6AX0gBYHsBAM+okBmzAqQr
1GhAgSqafxHs9a/aNdINQVp9APQiD5QK
=+1X6
-----END PGP PUBLIC KEY BLOCK-----

53
assets/pgp/hex.txt Normal file
View file

@ -0,0 +1,53 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
5jeQGlf9A7iXF80g
=1mQ+
-----END PGP PUBLIC KEY BLOCK-----

BIN
assets/ttf/JBM.ttf Normal file

Binary file not shown.

View file

@ -3,26 +3,25 @@ mod logger;
extern crate rocket;
extern crate rocket_dyn_templates;
use rocket::response::content::RawJson;
use rocket::{get, post, launch, build, routes};
use rocket::fs::FileServer;
use rocket_dyn_templates::{Template, context};
use rocket::serde::{Deserialize, Serialize, json::Json};
use rocket::serde::{json::Json, Deserialize, Serialize};
use rocket::{build, get, launch, post, routes};
use rocket_dyn_templates::{context, Template};
use chrono::Local;
use std::borrow::Cow;
use std::fs::read_to_string;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::fs::File;
use std::fs::read_to_string;
use serde_json::{Value, json};
use serde_json::{json, Value};
use crate::logger::iwakulog::{LogLevel, log};
use crate::logger::iwakulog::{log, LogLevel};
const ASSETS_DIR: &str = "./assets";
const GUEST_MESSAGES: &str = "./guests.json";
const ASSETS_DIR: &str = "./assets";
const GUEST_MESSAGES: &str = "./guests.json";
const DATE_TIME_FORMAT: &str = "%Y-%m-%d | %H:%M";
#[derive(Serialize, Deserialize)]
@ -32,7 +31,6 @@ struct GuestMessage<'r> {
body: Cow<'r, str>,
}
fn check_file(path: &str) -> bool {
Path::new(path).exists()
}
@ -46,7 +44,7 @@ fn read_guest_messages() -> Result<Value, Box<dyn std::error::Error>> {
fn post_guest_message(name: &str, body: &str) {
let mut guest_json = match read_guest_messages() {
Ok(x) => x,
Err(x) => panic!("Error while reading guest messages: {x:?}")
Err(x) => panic!("Error while reading guest messages: {x:?}"),
};
let messages = guest_json["messages"]
.as_array_mut()
@ -58,10 +56,21 @@ fn post_guest_message(name: &str, body: &str) {
"date": date.timestamp(),
}));
let mut file = File::create(GUEST_MESSAGES).expect("Couldn't read msgs");
file.write_all(guest_json.to_string().as_bytes()).expect("wah");
file.write_all(guest_json.to_string().as_bytes())
.expect("wah");
}
#[get("/abuse")]
fn abuse() -> Template {
Template::render("abuse", context! {})
}
#[get("/post")]
fn post() -> Template {
Template::render("post", context! {})
}
#[get("/members")]
fn members() -> Template {
Template::render("members", context! {})
}
#[get("/")]
fn index() -> Template {
@ -74,11 +83,16 @@ fn post_msg(input: Json<GuestMessage<'_>>) {
return;
}
#[get("/services")]
fn services() -> Template {
Template::render("services", context! {})
}
#[get("/guestbook")]
fn guests() -> Template {
let guest_json = match read_guest_messages() {
Ok(x) => x,
Err(x) => panic!("Error while reading guest messages: {x:?}")
Err(x) => panic!("Error while reading guest messages: {x:?}"),
};
Template::render("guest", &guest_json)
}
@ -86,13 +100,23 @@ fn guests() -> Template {
#[launch]
fn rocket() -> _ {
if !check_file(GUEST_MESSAGES) {
log(LogLevel::Warn, format!("Guest messages file ({}) has not been found. Creating a new one.", GUEST_MESSAGES).as_str());
log(
LogLevel::Warn,
format!(
"Guest messages file ({}) has not been found. Creating a new one.",
GUEST_MESSAGES
)
.as_str(),
);
let mut file = File::create(GUEST_MESSAGES).expect("Failed to create file.");
file.write_all(b"{\"messages\":[]}").expect("Failed to write to file.");
file.write_all(b"{\"messages\":[]}")
.expect("Failed to write to file.");
}
build()
.mount("/", routes![index, guests, post_msg])
.mount(
"/",
routes![index, guests, post_msg, members, post, services, abuse],
)
.mount("/assets", FileServer::from(ASSETS_DIR))
.attach(Template::fairing())
}

View file

@ -0,0 +1,159 @@
<title>Guest Book</title>
<div id="page-container">
<div id="header-container">
<h1 id="title"><a href="/">iwakura.rip</a></h1>
<p>Leave a nice message for others to read :)</p>
<p>Dates are in UTC+2/CEST.</p>
<a class="link" id="msg-post" onclick="show_message_poster()" style="margin-bottom: 10px;">&nbsp;[ post message ]&nbsp;</a>
</div>
<div id="entries-container">
{% for message in messages %}
<div class="guest-entry">
<div class="entry-header">
<bu class="entry-title">{{ message.name }}</bu>
<bu class="entry-date">{{ message.date | date(format="%Y-%m-%d | %H:%M", timezone="Europe/Amsterdam")}}</bu>
</div>
<div class="entry-body">
<p>{{ message.body }}</p>
</div>
</div>
{% endfor %}
</div>
<div id="post-container">
<bu id="name-label">name</bu>
<input type="text" id="name-box" name="name-box"><br>
<div class="break"></div>
<bu id="msg-label">message</bu>
<textarea id="msg-box"></textarea>
<div class="break"></div>
<a class="link" onclick="send_msg()">&nbsp;[ send ]&nbsp;</a>
</div>
</div>
<script>
let show_post_message = false;
let show_message_poster = () => {
if (!show_post_message) {
show_post_message = !show_post_message
document.getElementById("entries-container").style.display = "none";
document.getElementById("post-container").style.display = "flex";
document.getElementById("msg-post").innerText = " [ back ] ";
return
}
document.getElementById("msg-post").innerText = " [ post message ] "
show_post_message = !show_post_message
document.getElementById("entries-container").style.display = "flex";
document.getElementById("post-container").style.display = "none";
}
let send_msg = async () => {
fetch("/post_message", {
"method": "POST",
"body": JSON.stringify({
body: document.getElementById("msg-box").value,
name: document.getElementById("name-box").value
}),
}).then(x => {
window.location.reload()
})
}
</script>
<style>
a {
text-decoration: none;
}
a:active {
text-decoration: none;
}
:root {
--term-color: #4AF626;
--title-gap: 0px;
--title-font: "Hack Nerd Font";
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
#title {
background: url("/assets/img/lain.png");
background-position: -100px 1125px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 35px;
font-weight: bold;
text-align: center;
margin-bottom: calc(var(--title-gap) + 10px);
margin-top: var(--title-gap);
font-family: var(--title-font);
}
#post-container {
width: 50%;
padding: 5px;
border: 1px solid var(--term-color);
display: none;
margin: auto;
margin-top: 10px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
flex: 0 0 auto;
}
input {
margin-left: auto;
float: right;
}
.break {
flex-basis: 100%;
height: 0;
}
.link:hover {
background-color: var(--term-color);
color: black;
}
label {
text-align: left;
clear: both;
float: left;
}
.link {
cursor: default;
align-items: center;
margin-left: auto;
margin-right: auto;
text-align: center;
transition: 0.3s;
}
#header-container {
text-align: center;
}
#entries-container {
align-items: center;
gap: 10px;
margin-top: 10px;
display: flex;
flex-direction: column;
}
#page-container {
font-family: "Hack Nerd Font";
color: var(--term-color);
}
.guest-entry {
width: 50%;
padding: 5px;
border: 1px var(--term-color) solid;
}
.entry-header {
display: flex;
justify-content: space-between;
}
.entry-body {
font-size: 14px;
overflow: auto;
word-wrap: break-word;
}
bu {
font-weight: bold;
text-decoration: underline;
}
body {
background-color: black;
}
</style>

View file

@ -0,0 +1,159 @@
<div id="main-content">
<div id="middle-box">
<p style="text-align: center;margin-bottom: 5px;font-size: 20px;">[ iwakura.rip ]</p>
<img id="main-img" style="display:block;margin-left:auto;margin-right:auto;" src="https://media1.tenor.com/m/OlHMWq46CtAAAAAC/serial-experiments-lain-lain.gif" width="332" height="235">
<div class="link-container" id="service-container">
<a id="anim-1" href="https://mail.iwakura.rip">&nbsp;[ mail ]&nbsp;</a>
<a id="anim-2" href="https://git.iwakura.rip">&nbsp;[ git ]&nbsp;</a>
<a id="anim-3" href="https://media.iwakura.rip">&nbsp;[ media ]&nbsp;</a>
<a id="anim-4" href="https://blog.iwakura.rip">&nbsp;[ blog ]&nbsp;</a>
</div>
<div class="link-container" id="main-container">
<a onclick="showContainer(aboutContainer)">&nbsp;[ about ]&nbsp;</a>
<a onclick="showContainer(serviceContainer)">&nbsp;[ services ]&nbsp;</a>
<a href="/guestbook">&nbsp;[ guestbook ]&nbsp;</a>
<a href="/pgp">&nbsp;[ pgp ]&nbsp;</a>
</div>
<div class="link-container" id="about-container">
<a onclick="showSect(aboutSect)">&nbsp;[ i ]&nbsp;</a>
<a onclick="showSect(explaSect)">&nbsp;[ ? ]&nbsp;</a>
<a onclick="showSect(disclSect)">&nbsp;[ ! ]&nbsp;</a>
</div>
</div>
<br>
<div id="about-box" class="fadeIn">
<div id="about-sect">
<bu>About</bu>
<p>iwakura.rip is a collection of servers hosting mostly-private services for hexlocation & friends.</p>
<p>The iwakura.rip website is also connected to dn42 (<a href="https://iwakura.dn42">iwakura.dn42</a>). We are planning to connect our services to dn42 too.</p>
</div>
<div id="expla-sect">
<bu>Explanation</bu>
<p>Most of the gifs/art/names/ui design is inspired by/based on <a href="https://en.wikipedia.org/wiki/Serial_Experiments_Lain"><b>Serial Experiments Lain</b></a>, an anime series about Lain <u>Iwakura</u></p>
</div>
<div id="discl-sect">
<bu>Disclaimer</bu>
<p>Serial Experiments Lain is the property of Triangle Studios. iwakura.rip is not affiliated with Triangle Studios.</p>
</div>
</div>
</div>
<style>
@keyframes fadeIn {
to {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
bu {
font-weight: bold;
text-decoration: underline;
}
#expla-sect, #discl-sect, #about-sect {
opacity:0;
display:none;
}
.fadeIn {
animation: fadeIn 0.5s forwards;
}
.fadeOut {
animation: fadeOut 0.5s forwards;
}
:root {
--term-color: #4AF626;
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
a:hover {
color: black !important;
background-color: var(--term-color);
}
body {
background-color: black;
}
#main-container {
animation-delay: 0.2s;
}
a {
text-decoration: none;
transition: 0.3s;
cursor: default;
}
.link-container {
display: flex;
margin-top: 5px;
align-items: center;
justify-content: center;
transition: 0.5s;
opacity:0;
}
#service-container {
display: none;
}
#main-content, a {
font-family: "Hack Nerd Font";
color: var(--term-color);
}
#main-content {
/*font-family: "Hack Nerd Font";
color: var(--term-color);*/
position:absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<script>
let getId = (i) => document.getElementById(i);
let serviceContainer = getId('service-container');
let mainContainer = getId('main-container');
let aboutContainer = getId('about-container');
let aboutSect = getId('about-sect');
let disclSect = getId('discl-sect');
let explaSect = getId('expla-sect');
let sections = [aboutSect, disclSect, explaSect];
mainContainer.classList.add("fadeIn");
let containers = [serviceContainer, mainContainer, aboutContainer];
function showContainer(container){
for (let _container of containers) {
//_container.style.display = "none";
if (_container == container) continue
_container.classList.remove("fadeIn");
_container.style.display = "none"
}
container.classList.add("fadeIn");
container.style.display = "flex";
}
let showSect = (s) => {
for (let _s of sections) {
console.log(_s)
if (_s == s) continue;
_s.style.display = "none";
}
s.style.display = "block";
s.classList.add("fadeIn");
}
let showAbout = () => document.getElementById('about-box').style.display = "block";
document.getElementById("main-img").onclick = () => {
showContainer(mainContainer)
for (let _s of sections) {
_s.style.display="none";
_s.classList.remove("fadeIn");
}
}
</script>

View file

@ -0,0 +1,35 @@
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="main-content">
<p id="title">Make sure to verify our PGP keys when communicating with us.</p>
<a href="/assets/pgp/hex.txt" style="text-decoration: none">hex</a>
<a href="/assets/pgp/andre.txt" style="text-decoration: none">andre</a>
<p>Please encrypt any messages containing important details towards using our PGP keys. Thank you.</p>
</div>
</body>
<style>
:root {
--term-color: #4AF626;
}
#title {
font-weight: bold;
}
#main-content {
border: 1px var(--term-color) solid;
max-width: 50vw;
margin: auto;
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
body {
text-align: center;
color: var(--term-color);
font-family: "Hack Nerd Font";
background-color: black;
}
</style>
<!-- I'm on your side... -->

21
templates/abuse.html.tera Normal file
View file

@ -0,0 +1,21 @@
{% extends "base" %}
{% block title %}report abuse{% endblock title %}
{% block content %}
We ask that you report any abuse you find to: abuse@iwakura.rip.<br>
Please make sure your e-mail contains the following:
<ol>
<li>Type of abuse</li>
<li>Evidence (no screenshots, <b>hard evidence only</b>)</li>
<li>Origin of abuse (e-mail address, IP, domain etc)</li>
<li>Additional information that might help us.</li>
</ol>
Please consider the following when sending an abuse e-mail.
<ol>
<li>We are *not* able to provide any personal identifiable information, as we do not store them.</li>
<li>We take abuse notifications very serious. Sending us multiple false abuse reports will result in a permanent block from our mailserver.</li>
<li>We try to respond within 48 hours. Do not flood our inboxes.</li>
<li>Please be respectful at all times.</li>
</ol>
{% endblock content %}

22
templates/base.html.tera Normal file
View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}{% endblock title %} - iwakura.rip</title>
<link rel="stylesheet" href="/assets/css/global.css">
</head>
<body>
<div id="top">
<h1 style="font-size: 50px;text-align:center;margin:0;">iwakura.rip</h1><br>
<div id="link-container">
<a href="/">home</a>
<a href="/services">services</a>
<a href="/guestbook">guestbook</a>
<a href="/members">members</a>
<a href="/abuse">report abuse</a>
</div>
<hr>
<div id="content">{% block content %}{% endblock content %}</div>
</div>
</body>
</html>

View file

@ -1,159 +1,20 @@
<title>Guest Book</title>
<div id="page-container">
<div id="header-container">
<h1 id="title"><a href="/">iwakura.rip</a></h1>
<p>Leave a nice message for others to read :)</p>
<p>Dates are in UTC+2/CEST.</p>
<a class="link" id="msg-post" onclick="show_message_poster()" style="margin-bottom: 10px;">&nbsp;[ post message ]&nbsp;</a>
</div>
<div id="entries-container">
{% extends "base" %}
{% block title %}guestbook{% endblock title %}
{% block content %}
<p style="text-align:center;"><a href="/post">post a message?</a></p>
<hr>
<div id="entries">
{% for message in messages %}
<div class="guest-entry">
<div class="entry-header">
<bu class="entry-title">{{ message.name }}</bu>
<bu class="entry-date">{{ message.date | date(format="%Y-%m-%d | %H:%M", timezone="Europe/Amsterdam") }}</bu>
<bu class="entry-date">{{ message.date | date(format="%Y-%m-%d | %H:%M", timezone="Europe/Amsterdam")}}</bu>
</div>
<div class="entry-body">
<p>{{ message.body }}</p>
</div>
<hr>
</div>
{% endfor %}
</div>
<div id="post-container">
<bu id="name-label">name</bu>
<input type="text" id="name-box" name="name-box"><br>
<div class="break"></div>
<bu id="msg-label">message</bu>
<textarea id="msg-box"></textarea>
<div class="break"></div>
<a class="link" onclick="send_msg()">&nbsp;[ send ]&nbsp;</a>
</div>
</div>
<script>
let show_post_message = false;
let show_message_poster = () => {
if (!show_post_message) {
show_post_message = !show_post_message
document.getElementById("entries-container").style.display = "none";
document.getElementById("post-container").style.display = "flex";
document.getElementById("msg-post").innerText = " [ back ] ";
return
}
document.getElementById("msg-post").innerText = " [ post message ] "
show_post_message = !show_post_message
document.getElementById("entries-container").style.display = "flex";
document.getElementById("post-container").style.display = "none";
}
let send_msg = async () => {
fetch("/post_message", {
"method": "POST",
"body": JSON.stringify({
body: document.getElementById("msg-box").value,
name: document.getElementById("name-box").value
}),
}).then(x => {
window.location.reload()
})
}
</script>
<style>
a {
text-decoration: none;
}
a:active {
text-decoration: none;
}
:root {
--term-color: #4AF626;
--title-gap: 0px;
--title-font: "Hack Nerd Font";
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
#title {
background: url("/assets/img/lain.png");
background-position: -100px 1125px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 35px;
font-weight: bold;
text-align: center;
margin-bottom: calc(var(--title-gap) + 10px);
margin-top: var(--title-gap);
font-family: var(--title-font);
}
#post-container {
width: 50%;
padding: 5px;
border: 1px solid var(--term-color);
display: none;
margin: auto;
margin-top: 10px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
flex: 0 0 auto;
}
input {
margin-left: auto;
float: right;
}
.break {
flex-basis: 100%;
height: 0;
}
.link:hover {
background-color: var(--term-color);
color: black;
}
label {
text-align: left;
clear: both;
float: left;
}
.link {
cursor: default;
align-items: center;
margin-left: auto;
margin-right: auto;
text-align: center;
transition: 0.3s;
}
#header-container {
text-align: center;
}
#entries-container {
align-items: center;
gap: 10px;
margin-top: 10px;
display: flex;
flex-direction: column;
}
#page-container {
font-family: "Hack Nerd Font";
color: var(--term-color);
}
.guest-entry {
width: 50%;
padding: 5px;
border: 1px var(--term-color) solid;
}
.entry-header {
display: flex;
justify-content: space-between;
}
.entry-body {
font-size: 14px;
overflow: auto;
word-wrap: break-word;
}
bu {
font-weight: bold;
text-decoration: underline;
}
body {
background-color: black;
}
</style>
{% endblock content %}

View file

@ -1,158 +1,6 @@
<div id="main-content">
<div id="middle-box">
<p style="text-align: center;margin-bottom: 5px;font-size: 20px;">[ iwakura.rip ]</p>
<img id="main-img" style="display:block;margin-left:auto;margin-right:auto;" src="https://media1.tenor.com/m/OlHMWq46CtAAAAAC/serial-experiments-lain-lain.gif" width="332" height="235">
<div class="link-container" id="service-container">
<a id="anim-1" href="https://mail.iwakura.rip">&nbsp;[ mail ]&nbsp;</a>
<a id="anim-2" href="https://git.iwakura.rip">&nbsp;[ git ]&nbsp;</a>
<a id="anim-3" href="https://media.iwakura.rip">&nbsp;[ media ]&nbsp;</a>
<a id="anim-4" href="https://blog.iwakura.rip">&nbsp;[ blog ]&nbsp;</a>
</div>
<div class="link-container" id="main-container">
<a onclick="showContainer(aboutContainer)">&nbsp;[ about ]&nbsp;</a>
<a onclick="showContainer(serviceContainer)">&nbsp;[ services ]&nbsp;</a>
<a href="/guestbook">&nbsp;[ guestbook ]&nbsp;</a>
</div>
<div class="link-container" id="about-container">
<a onclick="showSect(aboutSect)">&nbsp;[ i ]&nbsp;</a>
<a onclick="showSect(explaSect)">&nbsp;[ ? ]&nbsp;</a>
<a onclick="showSect(disclSect)">&nbsp;[ ! ]&nbsp;</a>
</div>
</div>
<br>
<div id="about-box" class="fadeIn">
<div id="about-sect">
<bu>About</bu>
<p>iwakura.rip is a collection of servers hosting mostly-private services for hexlocation & friends.</p>
<p>The iwakura.rip website is also connected to dn42 (<a href="https://iwakura.dn42">iwakura.dn42</a>). We are planning to connect our services to dn42 too.</p>
</div>
<div id="expla-sect">
<bu>Explanation</bu>
<p>Most of the gifs/art/names/ui design is inspired by/based on <a href="https://en.wikipedia.org/wiki/Serial_Experiments_Lain"><b>Serial Experiments Lain</b></a>, an anime series about Lain <u>Iwakura</u></p>
</div>
<div id="discl-sect">
<bu>Disclaimer</bu>
<p>Serial Experiments Lain is the property of Triangle Studios. iwakura.rip is not affiliated with Triangle Studios.</p>
</div>
</div>
</div>
<style>
@keyframes fadeIn {
to {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
bu {
font-weight: bold;
text-decoration: underline;
}
#expla-sect, #discl-sect, #about-sect {
opacity:0;
display:none;
}
.fadeIn {
animation: fadeIn 0.5s forwards;
}
.fadeOut {
animation: fadeOut 0.5s forwards;
}
:root {
--term-color: #4AF626;
}
@font-face {
font-family: "Hack Nerd Font";
src: url(/assets/ttf/HNF-Reg.ttf);
}
a:hover {
color: black !important;
background-color: var(--term-color);
}
body {
background-color: black;
}
#main-container {
animation-delay: 0.2s;
}
a {
text-decoration: none;
transition: 0.3s;
cursor: default;
}
.link-container {
display: flex;
margin-top: 5px;
align-items: center;
justify-content: center;
transition: 0.5s;
opacity:0;
}
#service-container {
display: none;
}
#main-content, a {
font-family: "Hack Nerd Font";
color: var(--term-color);
}
#main-content {
/*font-family: "Hack Nerd Font";
color: var(--term-color);*/
position:absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<script>
let getId = (i) => document.getElementById(i);
let serviceContainer = getId('service-container');
let mainContainer = getId('main-container');
let aboutContainer = getId('about-container');
let aboutSect = getId('about-sect');
let disclSect = getId('discl-sect');
let explaSect = getId('expla-sect');
let sections = [aboutSect, disclSect, explaSect];
mainContainer.classList.add("fadeIn");
let containers = [serviceContainer, mainContainer, aboutContainer];
function showContainer(container){
for (let _container of containers) {
//_container.style.display = "none";
if (_container == container) continue
_container.classList.remove("fadeIn");
_container.style.display = "none"
}
container.classList.add("fadeIn");
container.style.display = "flex";
}
let showSect = (s) => {
for (let _s of sections) {
console.log(_s)
if (_s == s) continue;
_s.style.display = "none";
}
s.style.display = "block";
s.classList.add("fadeIn");
}
let showAbout = () => document.getElementById('about-box').style.display = "block";
document.getElementById("main-img").onclick = () => {
showContainer(mainContainer)
for (let _s of sections) {
_s.style.display="none";
_s.classList.remove("fadeIn");
}
}
</script>
{% extends "base" %}
{% block title %}homepage{% endblock title %}
{% block content %}
Welcome to iwakura.rip. We are a small group of technology nerds and geeks fascinated by computers and technology.<br>
We host a bunch of services on this domain for public usage. Want access? Just send me a pgp-encrypted email (hex[a]iwakura.rip) and introduce yourself :)
{% endblock content %}

View file

@ -0,0 +1,10 @@
{% macro service(title, description, href, img, h="16") %}
<div class="service-container">
<p class="service-title">
<img class="service-icon" src="{{img}}" height="{{h}}" >
<a href="{{href}}" class="service-link">{{title}}</a>
</p>
<hr />
<p class="service-description">{{description}}</p>
</div>
{% endmacro service %}

View file

@ -0,0 +1,9 @@
{% extends "base" %}
{% block title %}members{% endblock title %}
{% block content %}
Make sure to verify our PGP keys when communicating with us.
<ul>
<li><a href="/assets/pgp/andre.txt">andre</a></li>
<li><a href="/assets/pgp/hex.txt">hex</a></li>
</ul>
{% endblock content %}

26
templates/post.html.tera Normal file
View file

@ -0,0 +1,26 @@
{% extends "base" %}
{% block title %}post a message{% endblock title %}
{% block content %}
<div id="post-container">
<bu id="name-label">name</bu>
<input type="text" id="name-box" name="name-box"><br>
<div class="break"></div>
<bu id="msg-label">message</bu>
<textarea id="msg-box"></textarea>
<div class="break"></div>
<a class="link" onclick="send_msg()">send!</a>
</div>
<script>
let send_msg = async () => {
fetch("/post_message", {
"method": "POST",
"body": JSON.stringify({
body: document.getElementById("msg-box").value,
name: document.getElementById("name-box").value
}),
}).then(x => {
window.location.reload()
})
}
</script>
{% endblock content %}

View file

@ -0,0 +1,16 @@
{% import "macros" as macros %}
{% extends "base" %}
{% block title %}services{% endblock title %}
{% block content %}
<div id="service-containers">
{{macros::service(title="Forgejo", description="A place for everyone to host their source code!", href="https://git.iwakura.rip", img="https://www.marefa.org/w/images/thumb/0/05/Forgejo_logo.svg/640px-Forgejo_logo.svg.png")}}
{{macros::service(title="Jellyfin", description="For all your media consumption needs.", href="https://media.iwakura.rip", img="/assets/img/jellyfin.png")}}
{{macros::service(title="Woodpecker CI", description="Powerful CI/CD to use together with Forgejo.", href="https://ci.iwakura.rip", img="/assets/img/woodpecker.svg")}}
{{macros::service(title="Jellyseerr", description="Get information about your favorite movies and TV shows, all together in one place.", href="https://request.iwakura.rip", img="/assets/img/jellyseerr.ico")}}
{{macros::service(title="DN42", description="We are currently in the process of connecting all of our services to DN42 - an overlay network using internet technologies.", href="https://iwakura.dn42", img="/assets/img/dn42.png")}}
{{macros::service(title="Authelia", description="Open-source authentication & authorization platform.", href="https://a.iwakura.rip", img="/assets/img/authelia.png")}}
{{macros::service(title="E-mail", description="We are hosting our own e-mail servers on an off-shore hosting provider. Note: all emails are currently being stored in plain text. We recommend using PGP encryption.", href="https://mail.iwakura.rip", img="/assets/img/mail.png")}}
</div><br>
Other services can be added on request. We also try to provide space for members wanting to host their own services, though stability is something to think about when asking for this.
<p style="font-size: 10px">We do not own the copyright for any of the projects mentioned above. All copyright goes to their respective owners.</p>
{% endblock content %}