forked from sunwoo1524/krll
add menu and make possible for admin to edit rule
This commit is contained in:
parent
c2495565d9
commit
ffdddbd25b
|
@ -1,5 +1,6 @@
|
|||
NAME=Krll
|
||||
HOST=https://krll.me
|
||||
CONTACT=mailto:example@gmail.com
|
||||
|
||||
POSTGRES_HOST=db:5432
|
||||
POSTGRES_DATABASE=postgres
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,4 +6,6 @@ __pycache__/
|
|||
|
||||
docker-compose.yml
|
||||
|
||||
postgres/
|
||||
postgres/
|
||||
|
||||
rule.html
|
19
README.md
19
README.md
|
@ -1,11 +1,22 @@
|
|||
# Krll
|
||||
Krll, a privacy-friendly URL shortener
|
||||
Krll, a privacy-friendly open source URL shortener
|
||||
|
||||
https://krll.me
|
||||
|
||||
## Dev
|
||||
Copy `.env.example` to `.env` and edit it
|
||||
```
|
||||
## Run
|
||||
1. Copy `.env.example` to `.env` and edit it
|
||||
- NAME: Krll server's name(ex: Krll)
|
||||
- HOST: Krll server's host(ex: https://krll.me)
|
||||
- CONTACT: Server operator's contact info
|
||||
- POSTGRES_...: PostgreSQL setting(If you'll run postgresql with docker compose, you should edit just 'POSTGRES_PASSWORD', if not, you should edit 'POSTGRES_HOST' to your postgresql's host.)
|
||||
|
||||
2. RUN
|
||||
```bash
|
||||
# with docker compose
|
||||
cp docker-compose.example.yml docker-compose.yml
|
||||
docker compose up -d
|
||||
|
||||
# without docker compose
|
||||
python -m venv venv
|
||||
source ./venv/bin/activate/
|
||||
pip install -r requirements.txt
|
||||
|
|
19
main.py
19
main.py
|
@ -7,11 +7,17 @@ from fastapi.templating import Jinja2Templates
|
|||
from src.database import engine
|
||||
from src import models
|
||||
from src.routes.url import url_route
|
||||
from src.env import NAME, HOST, CONTACT
|
||||
|
||||
from src.env import NAME, HOST
|
||||
import os
|
||||
|
||||
|
||||
DEFAULT_CONTEXT = { "name": NAME, "host": HOST }
|
||||
# server's settings
|
||||
DEFAULT_CONTEXT = { "name": NAME, "host": HOST, "contact": CONTACT }
|
||||
|
||||
# server's rule page
|
||||
rule_f = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "rule.html"))
|
||||
RULE = "\n".join(rule_f.readlines())
|
||||
|
||||
|
||||
models.Base.metadata.create_all(bind=engine)
|
||||
|
@ -44,6 +50,15 @@ def index(request: Request):
|
|||
)
|
||||
|
||||
|
||||
@app.get("/rule", response_class=HTMLResponse)
|
||||
def rule(request: Request):
|
||||
return templates.TemplateResponse(
|
||||
request=request,
|
||||
name="rule_frame.html",
|
||||
context=DEFAULT_CONTEXT | { "rule": RULE }
|
||||
)
|
||||
|
||||
|
||||
@app.get("/about", response_class=HTMLResponse)
|
||||
def about(request: Request):
|
||||
return templates.TemplateResponse(
|
||||
|
|
5
rule.example.html
Normal file
5
rule.example.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<h1>Rule</h1>
|
||||
<ul>
|
||||
<li>Do not use Krll for spam.</li>
|
||||
<li>Be legal.</li>
|
||||
</ul>
|
|
@ -6,6 +6,7 @@ load_dotenv()
|
|||
|
||||
NAME = os.environ.get("NAME")
|
||||
HOST = os.environ.get("HOST")
|
||||
CONTACT = os.environ.get("CONTACT")
|
||||
|
||||
POSTGRES_DATABASE = os.environ.get("POSTGRES_DATABASE")
|
||||
POSTGRES_USER = os.environ.get("POSTGRES_USER")
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
main {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
section {
|
||||
|
@ -9,4 +11,5 @@ section {
|
|||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--link-color);
|
||||
}
|
BIN
static/images/logo.png
Normal file
BIN
static/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8 KiB |
|
@ -1,5 +1,8 @@
|
|||
main {
|
||||
align-items: center;
|
||||
padding-top: 100px;
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.input-container {
|
14
static/menu.js
Normal file
14
static/menu.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const menu_btn = document.getElementById("menu-btn");
|
||||
const menu = document.getElementById("menu");
|
||||
|
||||
menu_btn.onclick = () => {
|
||||
menu.classList.toggle("show");
|
||||
}
|
||||
|
||||
window.onclick = e => {
|
||||
if (!e.target.matches(".menu-btn")) {
|
||||
if (menu.classList.contains("show")) {
|
||||
menu.classList.remove("show");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
* {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
@ -13,7 +14,7 @@
|
|||
--text-color: light-dark(black, white);
|
||||
--footer-text-color: light-dark(rgb(90, 90, 90), rgb(173, 173, 173));
|
||||
--button-text-color: white;
|
||||
--link-color: light-dark(#2e2e2e, #7a7a7a);
|
||||
--link-color: light-dark(#797979, #9e9e9e);
|
||||
|
||||
--border-color: light-dark(lightgray, gray);
|
||||
--border-highlight-color: darkgray;
|
||||
|
@ -28,14 +29,68 @@ body {
|
|||
flex-direction: column;
|
||||
margin: 0;
|
||||
background-color: var(--background-color);
|
||||
padding-top: 100px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
main {
|
||||
header ul {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
flex: 1 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header ul * {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
header img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
header button {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
font-size: 17px;
|
||||
background-color: var(--input-background-color);
|
||||
position: absolute;
|
||||
margin-top: 5px;
|
||||
margin-left: 5px;
|
||||
border-radius: 5px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* @media screen and (max-width: 1000px) {
|
||||
.menu {
|
||||
width: 100vw;
|
||||
height: 100%;
|
||||
}
|
||||
} */
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
footer {
|
||||
|
|
15
static/rule/style.css
Normal file
15
static/rule/style.css
Normal file
|
@ -0,0 +1,15 @@
|
|||
main {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
section {
|
||||
width: 90%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--link-color);
|
||||
}
|
|
@ -10,26 +10,16 @@
|
|||
<main>
|
||||
<section>
|
||||
<h2>About Krll</h2>
|
||||
<p>Krll은 개인정보 수집 없이 URL을 단축하는 서비스입니다. 방해꾼 없이 빠르게 URL을 단축하고 공유하세요.</p>
|
||||
<p>repository: <a href="https://git.worldc.one/sunwoo1524/krll">https://git.worldc.one/sunwoo1524/krll</a></p>
|
||||
<p>Krll은 개인정보 수집이 없는 오픈 소스 링크 단축 서비스입니다.</p>
|
||||
|
||||
<h2>특징</h2>
|
||||
<ul>
|
||||
<li>개인정보 수집과 광고가 없습니다.</li>
|
||||
<li>단축 시 QR 코드가 함께 생성되어 다른 디바이스로 빠르게 공유할 수 있습니다.</li>
|
||||
<li>크롬, 파이어폭스 확장을 설치하여 웹사이트 내의 하이퍼링크를 우클릭 후 메뉴 선택 만으로 빠르게 단축할 수 있습니다.</li>
|
||||
</ul>
|
||||
<h3>기여하기</h3>
|
||||
<p>Krll은 MIT 라이센스가 적용되어 누구나 코드를 사용하고 이 프로젝트에 기여할 수 있습니다. 하지만 한 가지 부탁 드릴 것이 있습니다. <a href="https://nogithub.codeberg.page/">GitHub에 Krll의 코드를 업로드하지 말아주세요.</a></p>
|
||||
<p><a href="https://git.worldc.one/sunwoo1524/krll">자체 호스팅 중인 Forgejo</a>에서 기여할 수 있습니다.</p>
|
||||
|
||||
<h2>브라우저 확장</h2>
|
||||
<h3>브라우저 확장</h3>
|
||||
<p>크롬, 파이어폭스 확장을 설치하여 웹사이트 내의 하이퍼링크를 우클릭 후 메뉴 선택 만으로 빠르게 단축할 수 있습니다.</p>
|
||||
<p><a href="https://github.com/sunwoo1524/krll-chrome-extension">Chrome(스토어에 올라와있지 않아 직접 압축 파일로 다운로드하고 설치해야합니다.)</a></p>
|
||||
<p><a href="https://addons.mozilla.org/ko/firefox/addon/krll-url-shortener/">Firefox</a></p>
|
||||
|
||||
<h2>규칙</h2>
|
||||
<p>이것들을 막을 방법은 없지만 안정적인 서비스 운영을 위해서 따라주세요.</p>
|
||||
<ul>
|
||||
<li>대한민국 법에 저촉되는 링크를 단축하지 마세요.</li>
|
||||
<li>스팸을 위해서 사용하지 마세요.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='/style.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='/index/style.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
@ -25,5 +25,5 @@
|
|||
const host = "{{ host }}";
|
||||
</script>
|
||||
|
||||
<script src="{{ url_for('static', path='/script.js') }}"></script>
|
||||
<script src="{{ url_for('static', path='/index/script.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -7,14 +7,32 @@
|
|||
<title>{% block title %}{% endblock %}</title>
|
||||
<link rel="icon" href="{{ url_for('static', path='/favicon.ico') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='/root.css') }}">
|
||||
|
||||
<!-- Import Google Fonts Icons -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" />
|
||||
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<ul>
|
||||
<button class="menu-btn" id="menu-btn"><span class="menu-btn material-symbols-outlined">menu</span></button>
|
||||
<a href="/"><img src="{{ url_for('static', path='/images/logo.png') }}" alt="Krll Logo"></a>
|
||||
</ul>
|
||||
|
||||
<div class="menu" id="menu">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="https://git.worldc.one/sunwoo1524/krll">Git Repository</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
<footer>
|
||||
<p>스팸이나 불법적인 용도로 사용하지 말아주세요.</p>
|
||||
<p><a href="/about">About {{ name }}</a> · <a href="mailto:maengkkong1524@naver.com">Contact</a></p>
|
||||
<p><a href="/rule">Rule</a> · <a href="/about">About Krll</a> · <a href="{{ contact }}">Contact</a> · <a href="https://git.worldc.one/sunwoo1524/krll">Git Repository</a></p>
|
||||
</footer>
|
||||
|
||||
<script src="{{ url_for('static', path='/menu.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
15
templates/rule_frame.html
Normal file
15
templates/rule_frame.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block title %}About Krll{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='/rule/style.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main>
|
||||
<section>
|
||||
{{ rule|safe }}
|
||||
</section>
|
||||
</main>
|
||||
{% endblock %}
|
Loading…
Reference in a new issue