From ffdddbd25b858271aa823a82590fcb8606017585 Mon Sep 17 00:00:00 2001 From: sunwoo1524 Date: Sun, 5 May 2024 19:33:38 +0900 Subject: [PATCH] add menu and make possible for admin to edit rule --- .env.example | 1 + .gitignore | 4 +- README.md | 19 +++++++-- main.py | 19 ++++++++- rule.example.html | 5 +++ src/env.py | 1 + static/about/style.css | 3 ++ static/images/logo.png | Bin 0 -> 8222 bytes static/{ => index}/dQw4w9WgXcQ.js | 0 static/{ => index}/script.js | 0 static/{ => index}/style.css | 3 ++ static/menu.js | 14 +++++++ static/root.css | 65 +++++++++++++++++++++++++++--- static/rule/style.css | 15 +++++++ templates/about.html | 22 +++------- templates/index.html | 4 +- templates/layout.html | 22 +++++++++- templates/rule_frame.html | 15 +++++++ 18 files changed, 180 insertions(+), 32 deletions(-) create mode 100644 rule.example.html create mode 100644 static/images/logo.png rename static/{ => index}/dQw4w9WgXcQ.js (100%) rename static/{ => index}/script.js (100%) rename static/{ => index}/style.css (94%) create mode 100644 static/menu.js create mode 100644 static/rule/style.css create mode 100644 templates/rule_frame.html diff --git a/.env.example b/.env.example index aa48810..5734690 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ NAME=Krll HOST=https://krll.me +CONTACT=mailto:example@gmail.com POSTGRES_HOST=db:5432 POSTGRES_DATABASE=postgres diff --git a/.gitignore b/.gitignore index 85e47f7..b307255 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ __pycache__/ docker-compose.yml -postgres/ \ No newline at end of file +postgres/ + +rule.html \ No newline at end of file diff --git a/README.md b/README.md index ab8240b..c15f9ac 100644 --- a/README.md +++ b/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 diff --git a/main.py b/main.py index 9732edf..5d43557 100644 --- a/main.py +++ b/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( diff --git a/rule.example.html b/rule.example.html new file mode 100644 index 0000000..2595936 --- /dev/null +++ b/rule.example.html @@ -0,0 +1,5 @@ +

Rule

+ \ No newline at end of file diff --git a/src/env.py b/src/env.py index d88eb34..c79b859 100644 --- a/src/env.py +++ b/src/env.py @@ -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") diff --git a/static/about/style.css b/static/about/style.css index 9f768c6..950001c 100644 --- a/static/about/style.css +++ b/static/about/style.css @@ -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); } \ No newline at end of file diff --git a/static/images/logo.png b/static/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..81591e0bd6252a87e767718af67c8ec5bf006249 GIT binary patch literal 8222 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 QOaK4?07*qoM6N<$f|&HI0{{R3 literal 0 HcmV?d00001 diff --git a/static/dQw4w9WgXcQ.js b/static/index/dQw4w9WgXcQ.js similarity index 100% rename from static/dQw4w9WgXcQ.js rename to static/index/dQw4w9WgXcQ.js diff --git a/static/script.js b/static/index/script.js similarity index 100% rename from static/script.js rename to static/index/script.js diff --git a/static/style.css b/static/index/style.css similarity index 94% rename from static/style.css rename to static/index/style.css index 440f791..216f86b 100644 --- a/static/style.css +++ b/static/index/style.css @@ -1,5 +1,8 @@ main { align-items: center; + padding-top: 100px; + display: flex; + flex-direction:column; } .input-container { diff --git a/static/menu.js b/static/menu.js new file mode 100644 index 0000000..34f34b0 --- /dev/null +++ b/static/menu.js @@ -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"); + } + } +} \ No newline at end of file diff --git a/static/root.css b/static/root.css index cf6722f..936ac1e 100644 --- a/static/root.css +++ b/static/root.css @@ -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 { diff --git a/static/rule/style.css b/static/rule/style.css new file mode 100644 index 0000000..8dccca1 --- /dev/null +++ b/static/rule/style.css @@ -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); +} \ No newline at end of file diff --git a/templates/about.html b/templates/about.html index 654a7d6..44bab47 100644 --- a/templates/about.html +++ b/templates/about.html @@ -10,26 +10,16 @@

About Krll

-

Krll은 개인정보 수집 없이 URL을 단축하는 서비스입니다. 방해꾼 없이 빠르게 URL을 단축하고 공유하세요.

-

repository: https://git.worldc.one/sunwoo1524/krll

+

Krll은 개인정보 수집이 없는 오픈 소스 링크 단축 서비스입니다.

-

특징

-
    -
  • 개인정보 수집과 광고가 없습니다.
  • -
  • 단축 시 QR 코드가 함께 생성되어 다른 디바이스로 빠르게 공유할 수 있습니다.
  • -
  • 크롬, 파이어폭스 확장을 설치하여 웹사이트 내의 하이퍼링크를 우클릭 후 메뉴 선택 만으로 빠르게 단축할 수 있습니다.
  • -
+

기여하기

+

Krll은 MIT 라이센스가 적용되어 누구나 코드를 사용하고 이 프로젝트에 기여할 수 있습니다. 하지만 한 가지 부탁 드릴 것이 있습니다. GitHub에 Krll의 코드를 업로드하지 말아주세요.

+

자체 호스팅 중인 Forgejo에서 기여할 수 있습니다.

-

브라우저 확장

+

브라우저 확장

+

크롬, 파이어폭스 확장을 설치하여 웹사이트 내의 하이퍼링크를 우클릭 후 메뉴 선택 만으로 빠르게 단축할 수 있습니다.

Chrome(스토어에 올라와있지 않아 직접 압축 파일로 다운로드하고 설치해야합니다.)

Firefox

- -

규칙

-

이것들을 막을 방법은 없지만 안정적인 서비스 운영을 위해서 따라주세요.

-
    -
  • 대한민국 법에 저촉되는 링크를 단축하지 마세요.
  • -
  • 스팸을 위해서 사용하지 마세요.
  • -
{% endblock %} diff --git a/templates/index.html b/templates/index.html index 03de80d..de8246f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,7 +3,7 @@ {% block head %} {{ super() }} - + {% endblock %} {% block content %} @@ -25,5 +25,5 @@ const host = "{{ host }}"; - + {% endblock %} diff --git a/templates/layout.html b/templates/layout.html index 27b0459..2462b0b 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -7,14 +7,32 @@ {% block title %}{% endblock %} + + + + {% endblock %} +
+
    + + Krll Logo +
+ + +
+ {% block content %}{% endblock %} + + \ No newline at end of file diff --git a/templates/rule_frame.html b/templates/rule_frame.html new file mode 100644 index 0000000..69aaaeb --- /dev/null +++ b/templates/rule_frame.html @@ -0,0 +1,15 @@ +{% extends "layout.html" %} +{% block title %}About Krll{% endblock %} + +{% block head %} +{{ super() }} + +{% endblock %} + +{% block content %} +
+
+ {{ rule|safe }} +
+
+{% endblock %}