/
aska
/
Ask
Обзор
Документация
Войти
/
aska
/
Ask
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
program/app.py
111 строк
3 KB
andmigunv
Добавлены файлы сервиса коротких ссылок
08 июн 2026, 00:14
08 июн 2026, 00:14
0e2427c
Код
Авторство
О чём код?
import json import os import secrets import string from datetime import datetime from flask import Flask, redirect, render_template, request, url_for import redis app = Flask(__name__) REDIS_HOST = os.getenv("REDIS_HOST", "localhost") REDIS_PORT = int(os.getenv("REDIS_PORT", 6379)) BASE_URL = os.getenv("BASE_URL", "http://127.0.0.1:5000") r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, decode_responses=True) CODE_LENGTH = 6 CODE_CHARS = string.ascii_letters + string.digits def generate_code() -> str: while True: code = "".join(secrets.choice(CODE_CHARS) for _ in range(CODE_LENGTH)) if not r.exists(f"url:{code}"): return code def get_long_url(code: str) -> str | None: cached = r.get(f"cache:{code}") if cached: return cached long_url = r.get(f"url:{code}") if long_url: r.setex(f"cache:{code}", 3600, long_url) return long_url def record_visit(code: str) -> None: visit = { "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "ip": request.remote_addr or "unknown", "user_agent": request.headers.get("User-Agent", "unknown"), } r.incr(f"visits:{code}") r.lpush(f"history:{code}", json.dumps(visit, ensure_ascii=False)) r.ltrim(f"history:{code}", 0, 99) @app.route("/") def index(): return render_template("index.html", base_url=BASE_URL) @app.route("/create", methods=["POST"]) def create(): long_url = request.form.get("url", "").strip() if not long_url: return render_template("index.html", error="Введите URL", base_url=BASE_URL) if not long_url.startswith(("http://", "https://")): long_url = "https://" + long_url code = generate_code() r.set(f"url:{code}", long_url) r.set(f"visits:{code}", 0) short_url = f"{BASE_URL}/{code}" return render_template( "index.html", short_url=short_url, long_url=long_url, stats_url=url_for("stats", code=code), base_url=BASE_URL, ) @app.route("/<code>") def redirect_to(code: str): long_url = get_long_url(code) if not long_url: return render_template("index.html", error="Ссылка не найдена", base_url=BASE_URL), 404 record_visit(code) return redirect(long_url, code=302) @app.route("/stats/<code>") def stats(code: str): long_url = r.get(f"url:{code}") if not long_url: return render_template("index.html", error="Ссылка не найдена", base_url=BASE_URL), 404 total = int(r.get(f"visits:{code}") or 0) history_raw = r.lrange(f"history:{code}", 0, 49) history = [json.loads(item) for item in history_raw] return render_template( "stats.html", code=code, long_url=long_url, short_url=f"{BASE_URL}/{code}", total=total, history=history, base_url=BASE_URL, ) if __name__ == "__main__": app.run(debug=True, host="127.0.0.1", port=5000)