Wrapper script with disconnect handling; Basic dark mode fix; Include all assets locally
This commit is contained in:
parent
ef797f127c
commit
b412e04726
|
@ -1,5 +1,6 @@
|
|||
*.session
|
||||
*.session-journal
|
||||
*.session.bak
|
||||
.env
|
||||
__pycache__/
|
||||
venv/
|
||||
|
@ -12,3 +13,4 @@ Procfile
|
|||
.vscode/
|
||||
.gitignore
|
||||
pyproject.toml
|
||||
*.bak
|
||||
|
|
|
@ -3,10 +3,8 @@ import logging
|
|||
from .main import Indexer
|
||||
from .config import debug
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
|
||||
logging.getLogger("telethon").setLevel(logging.INFO if debug else logging.ERROR)
|
||||
logging.getLogger("aiohttp").setLevel(logging.INFO if debug else logging.ERROR)
|
||||
|
||||
|
||||
Indexer().run()
|
||||
|
|
|
@ -5,7 +5,6 @@ import json
|
|||
import sys
|
||||
import os
|
||||
|
||||
|
||||
try:
|
||||
port = int(os.environ.get("PORT", "8080"))
|
||||
except Exception as e:
|
||||
|
@ -45,6 +44,7 @@ password = os.environ.get("PASSWORD", "")
|
|||
SHORT_URL_LEN = int(os.environ.get("SHORT_URL_LEN", 3))
|
||||
authenticated = bool(username and password)
|
||||
SESSION_COOKIE_LIFETIME = int(os.environ.get("SESSION_COOKIE_LIFETIME") or "60")
|
||||
|
||||
try:
|
||||
SECRET_KEY = os.environ["SECRET_KEY"]
|
||||
if len(SECRET_KEY) != 32:
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
0
app/templates/js/filesaver.min.js → app/res/js/filesaver.min.js
vendored
Normal file → Executable file
0
app/templates/js/filesaver.min.js → app/res/js/filesaver.min.js
vendored
Normal file → Executable file
0
app/templates/js/fluidplayer.min.js → app/res/js/fluidplayer.min.js
vendored
Normal file → Executable file
0
app/templates/js/fluidplayer.min.js → app/res/js/fluidplayer.min.js
vendored
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
from typing import List
|
||||
from os import path
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp.web_routedef import RouteDef
|
||||
|
@ -10,7 +11,6 @@ from .views import Views
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_common_routes(handler: Views, alias_id: str) -> List[RouteDef]:
|
||||
p = "/{chat:" + alias_id + "}"
|
||||
return [
|
||||
|
@ -34,7 +34,6 @@ def get_common_routes(handler: Views, alias_id: str) -> List[RouteDef]:
|
|||
),
|
||||
]
|
||||
|
||||
|
||||
async def setup_routes(app: web.Application, handler: Views):
|
||||
client = handler.client
|
||||
index_all = index_settings["index_all"]
|
||||
|
@ -49,6 +48,7 @@ async def setup_routes(app: web.Application, handler: Views):
|
|||
web.post("/login", handler.login_post, name="login_handle"),
|
||||
web.get("/logout", handler.logout_get, name="logout"),
|
||||
web.get("/favicon.ico", handler.faviconicon, name="favicon"),
|
||||
web.static("/static_res", f"{path.dirname(path.abspath(__file__))}/res", name="static_res"),
|
||||
]
|
||||
|
||||
if index_all:
|
||||
|
|
|
@ -4,7 +4,6 @@ import asyncio
|
|||
|
||||
from telethon import TelegramClient, utils
|
||||
|
||||
|
||||
class Client(TelegramClient):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__("tg-index.session", *args, **kwargs)
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
</div>
|
||||
|
||||
<script>
|
||||
function toggleTheme() {
|
||||
var Doc = document.documentElement;
|
||||
var Class = Array.from(Doc.classList);
|
||||
if (Class.includes('light')) {
|
||||
Doc.className = 'dark';
|
||||
localStorage.theme = 'dark';
|
||||
} else
|
||||
if (Class.includes('dark')) {
|
||||
Doc.className = 'light';
|
||||
localStorage.theme = 'light';
|
||||
};
|
||||
// var Doc = document.documentElement;
|
||||
// var Class = Array.from(Doc.classList);
|
||||
// if (Class.includes('light')) {
|
||||
// Doc.className = 'dark';
|
||||
// localStorage.theme = 'dark';
|
||||
// } else
|
||||
// if (Class.includes('dark')) {
|
||||
// Doc.className = 'light';
|
||||
// localStorage.theme = 'light';
|
||||
// };
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -3,26 +3,48 @@
|
|||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.1.4/dist/tailwind-dark.min.css" href_="https://cdn.jsdelivr.net/npm/tailwindcss@2.1.4/dist/tailwind.min.css" rel="stylesheet"/>
|
||||
<script type="text/javascript">
|
||||
{% include "./js/fluidplayer.min.js" %}
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var Doc = document.documentElement;
|
||||
Doc.className = 'light';
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
Doc.className = 'dark';
|
||||
} else {
|
||||
Doc.className = 'light';
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
<link href="{{ app.router['static_res'].url_for(filename='css/tailwind.rx.css') }}" rel="stylesheet"/>
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Roboto', 'Liberation Sans', 'Noto Sans', sans-serif;
|
||||
}
|
||||
</style>
|
||||
<style id="StylesheetDarkTheme">
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000000 !important;
|
||||
}
|
||||
.shadow {
|
||||
--tw-shadow: 0 1px 3px 0 rgba(255, 255, 255, 0.1), 0 1px 2px 0 rgba(255, 255, 255, 0.06);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 255 255 #FFFF), var(--tw-ring-shadow, 255 255 #FFFF), var(--tw-shadow);
|
||||
}
|
||||
.hover\:shadow-lg:hover {
|
||||
--tw-shadow: 0 10px 15px -3px rgba(255, 255, 255, 0.1), 0 4px 6px -2px rgba(255, 255, 255, 0.05);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 255 255 #FFFF), var(--tw-ring-shadow, 255 255 #FFFF), var(--tw-shadow);
|
||||
}
|
||||
.TgMessageCard {
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.TgChatCard:hover {
|
||||
background-color: #241501;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="{{ app.router['static_res'].url_for(filename='js/fluidplayer.min.js') }}" type="text/javascript"></script>
|
||||
<script>
|
||||
(function(){
|
||||
// var Doc = document.documentElement;
|
||||
// Doc.className = 'light';
|
||||
// if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
// Doc.className = 'dark';
|
||||
// //StylesheetDarkTheme.innerHTML = StylesheetDarkTheme.innerHTML.trim().split('{').slice(1).join('{').split('}').slice(0, -1).join('}');
|
||||
// } else {
|
||||
// Doc.className = 'light';
|
||||
// //StylesheetDarkTheme.innerHTML = `@media (prefers-color-scheme: dark) { ${StylesheetDarkTheme.innerHTML} }`;
|
||||
// };
|
||||
})();
|
||||
</script>
|
||||
<title>
|
||||
{% if title %} {{title}} {% else %} Telegram Index {% endif %}
|
||||
</title>
|
||||
|
@ -37,12 +59,12 @@
|
|||
<span style="vertical-align: super; white-space: pre;">[<a
|
||||
href="https://github.com/octospacc/TelegramIndex-Fork" class="font-bold underline"
|
||||
>Source Code</a>]</span>
|
||||
<button onclick="toggleTheme()" class="rounded-full bg-white">
|
||||
<img src="https://s3.imgcdn.dev/nW9YV.png" class="h-8" alt="Theme"/>
|
||||
</button>
|
||||
<!--<button onclick="toggleTheme()" class="rounded-full bg-white">
|
||||
<img src="{{ app.router['static_res'].url_for(filename='icons/sun.png') }}" class="h-8" alt="Theme"/>
|
||||
</button>-->
|
||||
{% if authenticated %}
|
||||
<button class="rounded-full bg-white"><a href="/logout">
|
||||
<img src="https://s3.imgcdn.dev/ndsjh.png" class="h-8" alt="Logout">
|
||||
<img src="{{ app.router['static_res'].url_for(filename='icons/logout.png') }}" class="h-8" alt="Logout">
|
||||
</a></button>
|
||||
{% else %} {% endif %}
|
||||
</div>
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
<div class="flex flex-wrap gap-4 justify-center w-full">
|
||||
{% for chat in chats %}
|
||||
<a href="/{{chat.page_id}}" title="{{chat.name}}"
|
||||
class="justify-items-center min-h-full w-5/12 sm:w-1/4 md:w-1/5 lg:w-1/6 rounded p-2 text-center break-words shadow hover:shadow-md hover:bg-blue-100 dark:bg-red-700 dark:hover:bg-red-500">
|
||||
|
||||
class="TgChatCard justify-items-center min-h-full w-5/12 sm:w-1/4 md:w-1/5 lg:w-1/6 rounded p-2 text-center break-words shadow hover:shadow-md hover:bg-blue-100 dark:bg-red-700 dark:hover:bg-red-500"
|
||||
>
|
||||
<img src="/{{chat.page_id}}/logo?big=1" class="w-full rounded-full"/>
|
||||
<div class="p-1 mt-2 rounded text-white bg-blue-500 dark:bg-yellow-500">{{chat.name}}</div>
|
||||
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
{% include 'header.html' %} {% block javascript %}
|
||||
<script type="text/javascript">
|
||||
{% include "./js/filesaver.min.js" %}
|
||||
{% include "./js/playlist.js" %}
|
||||
</script>
|
||||
<script src="{{ app.router['static_res'].url_for(filename='js/filesaver.min.js') }}" type="text/javascript"></script>
|
||||
<script src="{{ app.router['static_res'].url_for(filename='js/playlist.js') }}" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
|
||||
<div class="block md:flex justify-between items-center px-4 text-center border-b-2">
|
||||
|
@ -45,7 +43,7 @@
|
|||
|
||||
<!-- Card -->
|
||||
<div title="{% if item.media %} {{item.mime_type}} | {{item.human_size}} {% else %} Text message {% endif %}"
|
||||
class="text-sm items-center justify-center w-full min-h-full sm:w-2/5 md:w-1/4 lg:w-1/6 rounded m-2 shadow hover:shadow-lg dark:bg-red-700">
|
||||
class="TgMessageCard text-sm items-center justify-center w-full min-h-full sm:w-2/5 md:w-1/4 lg:w-1/6 rounded m-2 shadow hover:shadow-lg dark:bg-black-700">
|
||||
|
||||
{% if item.media %}
|
||||
|
||||
|
@ -128,7 +126,7 @@
|
|||
|
||||
{% else %}
|
||||
|
||||
<p class="my-4 text-center text-2xl md:text-3xl lg:text-4xl xl:text-5xl">
|
||||
<p data-text="No message to display!" class="my-4 text-center text-2xl md:text-3xl lg:text-4xl xl:text-5xl">
|
||||
No message to display!
|
||||
</p>
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ from urllib.parse import quote
|
|||
|
||||
from telethon.tl.custom import Message
|
||||
|
||||
|
||||
def get_file_name(message: Message, quote_name: bool = True) -> str:
|
||||
if message.file.name:
|
||||
name = message.file.name
|
||||
|
@ -12,7 +11,6 @@ def get_file_name(message: Message, quote_name: bool = True) -> str:
|
|||
name = f"{message.date.strftime('%Y-%m-%d_%H:%M:%S')}{ext}"
|
||||
return quote(name) if quote_name else name
|
||||
|
||||
|
||||
def get_human_size(num: Union[int, float]) -> str:
|
||||
base = 1024.0
|
||||
sufix_list = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
|
||||
|
|
|
@ -18,10 +18,8 @@ from .logout_view import LogoutView
|
|||
from .faviconicon_view import FaviconIconView
|
||||
from .middlewhere import middleware_factory
|
||||
|
||||
|
||||
TELEGRAM_CHAT = Union[Chat, User, Channel]
|
||||
|
||||
|
||||
class Views(
|
||||
HomeView,
|
||||
Download,
|
||||
|
|
|
@ -4,10 +4,8 @@ from telethon.tl.types import Chat, User, Channel
|
|||
|
||||
from ..telegram import Client
|
||||
|
||||
|
||||
TELEGRAM_CHAT = Union[Chat, User, Channel]
|
||||
|
||||
|
||||
class BaseView:
|
||||
client: Client
|
||||
url_len: int
|
||||
|
|
|
@ -7,10 +7,8 @@ from app.util import get_file_name
|
|||
from app.config import block_downloads
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Download(BaseView):
|
||||
async def download_get(self, req: web.Request) -> web.Response:
|
||||
return await self.handle_request(req)
|
||||
|
|
|
@ -6,7 +6,6 @@ from aiohttp import web
|
|||
from app.config import logo_folder
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
class FaviconIconView(BaseView):
|
||||
async def faviconicon(self, req: web.Request) -> web.Response:
|
||||
favicon_path = logo_folder.joinpath("favicon.ico")
|
||||
|
|
|
@ -3,7 +3,6 @@ import aiohttp_jinja2
|
|||
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
class HomeView(BaseView):
|
||||
@aiohttp_jinja2.template("home.html")
|
||||
async def home(self, req: web.Request) -> web.Response:
|
||||
|
|
|
@ -10,10 +10,8 @@ from app.config import results_per_page, block_downloads
|
|||
from app.util import get_file_name, get_human_size
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IndexView(BaseView):
|
||||
@aiohttp_jinja2.template("index.html")
|
||||
async def index(self, req: web.Request) -> web.Response:
|
||||
|
|
|
@ -11,10 +11,8 @@ from app.util import get_file_name, get_human_size
|
|||
from app.config import block_downloads
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InfoView(BaseView):
|
||||
@aiohttp_jinja2.template("info.html")
|
||||
async def info(self, req: web.Request) -> web.Response:
|
||||
|
@ -63,7 +61,7 @@ class InfoView(BaseView):
|
|||
media["image"] = True
|
||||
|
||||
if message.text:
|
||||
caption = message.raw_text
|
||||
caption = message.text #message.raw_text
|
||||
else:
|
||||
caption = ""
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import aiohttp_jinja2
|
|||
from aiohttp_session import new_session
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
class LoginView(BaseView):
|
||||
@aiohttp_jinja2.template("login.html")
|
||||
async def login_get(self, req: web.Request) -> web.Response:
|
||||
|
|
|
@ -5,14 +5,11 @@ import random
|
|||
from aiohttp import web
|
||||
from telethon.tl import types
|
||||
|
||||
|
||||
from app.config import logo_folder
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LogoView(BaseView):
|
||||
async def logo(self, req: web.Request) -> web.Response:
|
||||
alias_id = req.match_info["chat"]
|
||||
|
@ -40,10 +37,11 @@ class LogoView(BaseView):
|
|||
im = Image.new("RGB", (W, H), color)
|
||||
draw = ImageDraw.Draw(im)
|
||||
font = ImageFont.truetype("arial.ttf", 50)
|
||||
w, h = draw.textsize(chat_name, font=font)
|
||||
draw.text(
|
||||
((W - w) / 2, (H - h) / 2), chat_name, fill="white", font=font
|
||||
)
|
||||
#w, h = draw.textsize(chat_name, font=font)
|
||||
#draw.text(
|
||||
# ((W - w) / 2, (H - h) / 2), chat_name, fill="white", font=font
|
||||
#)
|
||||
draw.text((W, H), chat_name, fill="white", font=font)
|
||||
im.save(logo_path)
|
||||
else:
|
||||
pos = -1 if req.query.get("big", None) else int(len(photo.sizes) / 2)
|
||||
|
|
|
@ -3,7 +3,6 @@ from aiohttp import web
|
|||
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
class LogoutView(BaseView):
|
||||
async def logout_get(self, req: web.Request) -> web.Response:
|
||||
session = await get_session(req)
|
||||
|
|
|
@ -6,10 +6,8 @@ from aiohttp.web import middleware, HTTPFound, Response, Request
|
|||
from aiohttp import BasicAuth, hdrs
|
||||
from aiohttp_session import get_session
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _do_basic_auth_check(request: Request) -> Union[None, bool]:
|
||||
if "download_" not in request.match_info.route.name:
|
||||
return
|
||||
|
@ -47,7 +45,6 @@ def _do_basic_auth_check(request: Request) -> Union[None, bool]:
|
|||
|
||||
return True
|
||||
|
||||
|
||||
async def _do_cookies_auth_check(request: Request) -> Union[None, bool]:
|
||||
session = await get_session(request)
|
||||
if not session.get("logged_in", False):
|
||||
|
@ -56,7 +53,6 @@ async def _do_cookies_auth_check(request: Request) -> Union[None, bool]:
|
|||
session["last_at"] = time.time()
|
||||
return True
|
||||
|
||||
|
||||
def middleware_factory() -> Coroutine:
|
||||
@middleware
|
||||
async def factory(request: Request, handler: Coroutine) -> Response:
|
||||
|
|
|
@ -8,10 +8,8 @@ from telethon.tl import types, custom
|
|||
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThumbnailView(BaseView):
|
||||
async def thumbnail_get(self, req: web.Request) -> web.Response:
|
||||
file_id = int(req.match_info["id"])
|
||||
|
|
|
@ -2,7 +2,6 @@ from aiohttp import web
|
|||
|
||||
from .base import BaseView
|
||||
|
||||
|
||||
class WildcardView(BaseView):
|
||||
async def wildcard(self, req: web.Request) -> web.Response:
|
||||
return web.HTTPFound("/")
|
||||
|
|
Loading…
Reference in New Issue