Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat+Fix: bug fix for windows ,new dark theme , fix playlist download, new file icon, new font #60

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
33cbeba
🙈 ignore test .env
rayanfer32 Jun 13, 2021
7141a83
Merge branch 'master' of https://github.com/rayanfer32/tg-index
rayanfer32 Jun 13, 2021
9f8668e
Merge branch 'master' of https://github.com/rayanfer32/tg-index
rayanfer32 Jun 14, 2021
162f879
Merge branch 'master' of https://github.com/rayanfer32/tg-index
rayanfer32 Jun 21, 2021
ffdf231
Merge branch 'odysseusmax:master' into master
rayanfer32 Apr 29, 2022
42400c0
.venv ignored
rayanfer32 Apr 29, 2022
de6940a
Merge branch 'master' of https://github.com/rayanfer32/tg-index
rayanfer32 Apr 29, 2022
f4bbb44
🐛 fix for windows
rayanfer32 Apr 29, 2022
b4ed654
add eye saving purple theme
rayanfer32 Apr 29, 2022
241c4a3
fix playlist download
rayanfer32 Apr 29, 2022
7952918
fix dark mode
rayanfer32 Apr 29, 2022
3752166
fix dark mode
rayanfer32 Apr 29, 2022
0971081
Merge branch 'develop' of https://github.com/rayanfer32/tg-index into…
rayanfer32 Apr 29, 2022
a65ecbe
add file icon
rayanfer32 Apr 30, 2022
f9c565a
Merge pull request #1 from rayanfer32/develop
rayanfer32 Apr 30, 2022
e4ba090
🚑 run safe for repl.it to prevent session expiration
rayanfer32 Jun 6, 2022
72e5f15
🔧 repl.it config
rayanfer32 Jun 6, 2022
316e845
🐛 ✏️ timeout is_alive(), fix self.loop error
rayanfer32 Jun 6, 2022
533ce3a
💄 improve UI, selectable <a> text
rayanfer32 Jun 8, 2022
24f6366
fix: filename on save
rayanfer32 Jul 25, 2022
6034175
fix: kill repl session if not responding
rayanfer32 Jan 21, 2023
3abd686
fix: check process if its running before running new instance
rayanfer32 Jan 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*.session
.env
*.env
__pycache__/
venv/
tests/
Expand All @@ -10,4 +10,5 @@ app.json
Procfile
.vscode/
.gitignore
pyproject.toml
.venv/
pyproject.toml
2 changes: 2 additions & 0 deletions .replit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
language="bash"
run="chmod +x main.sh;./main.sh"
1 change: 1 addition & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
logo_folder.mkdir(parents=True, exist_ok=True)
username = os.environ.get("TGINDEX_USERNAME", "")
password = os.environ.get("PASSWORD", "")
file_icon_path = "app/icons/document-icon.png"
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")
Expand Down
Binary file added app/icons/document-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ async def cleanup(self, server: web.Application):
log.debug("telegram client disconnected!")

def run(self):
web.run_app(self.server, host=host, port=port, loop=self.loop)
web.run_app(self.server, host=host, port=port)
14 changes: 7 additions & 7 deletions app/templates/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<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" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind-dark.min.css" integrity="sha512-5qCImO4bnvlpsqNsYuZEHlzJhEN3MBqd3GZp0QCJS0gVNq3Q+MT9Msw8c4UT2j5Cuq/29kz3jCmgYJpekNqSMQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdn.fluidplayer.com/v3/current/fluidplayer.min.js">

</script>
Expand All @@ -16,9 +16,9 @@
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Google+Sans:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
* {
font-family: 'Roboto', sans-serif;
font-family: 'Google Sans', sans-serif;
}
</style>

Expand All @@ -28,13 +28,13 @@

</head>

<body class="bg-white text-black dark:bg-black dark:text-white">
<body class="bg-white text-black dark:bg-gray-800 dark:text-white ">

<header class="bg-blue-300 dark:bg-red-500 text-white mb-2 p-2 w-full shadow">
<header class="bg-blue-500 dark:bg-gray-900 text-white mb-2 p-2 w-full shadow-md">
<div class="flex mx-auto justify-between items-center max-w-screen-xl">
<a href="/" id="title-a" class="text-left font-bold text-xl lg:text-2xl xl:text-3xl"> Telegram index </a>
<a href="/" id="title-a" class="text-left font-normal text-l lg:text-2xl xl:text-3xl p-2"> Telegram index </a>
<div class="space-x-1">
<button onclick="toggleTheme()" class="rounded-full bg-white">
<button onclick="toggleTheme()" class="rounded-full bg-white dark:bg-gray-500">
<img src="https://s3.imgcdn.dev/nW9YV.png" class="h-8" alt="Theme">
</button>
{% if authenticated %}
Expand Down
9 changes: 4 additions & 5 deletions app/templates/home.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
{% include 'header.html' %}

<h1 class=" my-2 text-2xl text-center font-bold text-green-400">
<h1 class=" my-2 text-2xl text-center font-bold ">
Available Sources
</h1>

<div class="mx-auto my-1 p-1 w-full">
<div class="flex flex-wrap gap-4 justify-center w-full">
{% for chat in chats %}
<a title="{{chat.name}}" href="/{{chat.page_id}}"
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">

<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>
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-gray-500 dark:hover:bg-gray-400">

<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-blue-500 dark:text-white">{{chat.name}}</div>
</a>
{% endfor %}
</div>
Expand Down
54 changes: 29 additions & 25 deletions app/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
{% include 'header.html' %} {% block javascript %}
<script type="text/javascript">
{% include "./js/filesaver.min.js" %}
{% include "./js/playlist.js" %}

</script>
{% endblock %}

<div class="block md:flex justify-between items-center px-4 text-center border-b-2">
<div class="m-2 block md:flex items-center justify-center md:justify-start text-2xl md:text-right font-bold text-blue-500">
<img class="mx-auto md:ml-0 md:mr-1 my-4 md:my-2 w-16 h-16 rounded-full bg-black outline-none" src="{{logo}}">
<a href="javascript:window.location.href=window.location.href"> {{name}} </a>
<div class="block md:flex justify-between items-center px-4 text-center">

<!-- * channel logo and name -->
<div class="flex m-2 block bg-gray-200 dark:bg-gray-700 rounded-full shadow-inner shadow-md px-2 items-center justify-center">
<img class="my-1 w-12 h-12 rounded-full bg-black outline-none" src="{{logo}}">
<a class="mx-1" href="javascript:window.location.href=window.location.href">
{{name}}
</a>
</div>

<div class="m-2">
<!-- * search bar-->
<div class="m-1">
<form class="">

<div class="my-4 md:my-2">
<div class="flex items-center rounded-full shadow dark:bg-white">
<input class="rounded-l-full w-full py-1 px-6 text-gray-700 leading-tight focus:outline-none dark:text-black"
<div class="my-2 md:my-1">
<div class="flex items-center rounded-full shadow dark:bg-gray-500">
<input class="rounded-full w-full py-1 px-6 dark:text-white dark:bg-gray-500 leading-tight focus:outline-none dark:text-black"
name="search" id="search" value="{% if search %}{{search}}{% endif %}" type="text"
placeholder="Search">
<div class="p-1">
<button
class="bg-blue-500 text-white rounded-full p-2 hover:bg-blue-400 focus:outline-none w-12 h-12 flex items-center justify-center">
class="bg-blue-500 text-white rounded-full p-1 hover:bg-blue-400 focus:outline-none w-12 h-12 flex items-center justify-center">
<div><svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
Expand All @@ -47,18 +49,19 @@
<!-- Card -->
<div title="{% if item.media %} {{item.mime_type}} | {{item.human_size}} {% else %} Text message {% endif %}"
href="{{item.url}}"
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="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-gray-500">
{% if item.media %}
<div class="absolute bg-blue-600 rounded-full dark:bg-blue-600 text-white my-1 mx-6 py-0 px-1">{{item.file_id}}</div>

<a href="{{item.url}}"><img src="{{item.thumbnail}}" class="w-full rounded shadow-inner"></a>
<div class="p-2">{{item.insight}}</div>
<a href="{{item.url}}"><img src="{{item.thumbnail}}" class="w-full object-scale-down h-32 rounded shadow-inner"></a>
<div class="p-2 fill-blue-400">{{item.insight}}</div>
<!-- Buttons container -->
<span class="inline-flex mb-1 rounded shadow-inner dark:bg-green-500">
<span class="inline-flex mb-1 rounded shadow-inner dark:bg-blue-400">
{% if not block_downloads %}
<!-- Direct file download button -->
<a href="{{item.download}}"
class="flex-1 hover:bg-blue-300 text-gray-900 font-semibold py-1 px-2 rounded items-center">
class="flex-1 hover:bg-blue-500 text-gray-900 font-semibold py-1 px-2 rounded items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
Expand All @@ -80,7 +83,7 @@
</a>

<!-- One click single item playlist Download -->
<button title="{{item.filename}}.m3u" onclick="singleItemPlaylist('{{item.download}}','{{item.filename}}', '{{m3u_option}}');"
<button title="{{item.filename}}.m3u" onclick="singleItemPlaylist('{{item.download}}','{{item.quoted_filename}}', '{{m3u_option}}');"
class="flex-1 hover:bg-blue-300 text-gray-900 font-semibold py-1 px-2 rounded items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
Expand All @@ -94,12 +97,13 @@
</span>

{% else %}
<a href={{item.url}}>
<div class="p-4 rounded shadow-inner rounded text-dark py-0 px-2">{{item.insight}}</div>
<a style="-webkit-user-select: all;-moz-user-select: all;-ms-user-select: all;user-select: all;" href={{item.url}}>
<div class="p-4 rounded shadow-inner text-dark py-0 px-2">{{item.insight}}</div>
</a>
<div class="bg-blue-600 rounded-full dark:bg-blue-600 text-white my-1 mx-6 py-0 px-1">{{item.file_id}}</div>
{% endif %}
<div class="bg-blue-500 rounded text-white my-1 py-0 px-1">{{item.file_id}}</div>


</div>


Expand All @@ -115,15 +119,15 @@
<div class="mx-auto my-2 text-center flex text-white content-center justify-center">
{% if prev_page %}
<a title="Previous page"
class="mx-2 p-2 border rounded bg-green-500 hover:border-green-500 hover:text-green-500 hover:bg-white"
class="mx-2 p-2 border rounded bg-blue-500 hover:border-blue-500 hover:text-blue-500 hover:bg-white"
href="{{prev_page.url}}">Page {{prev_page.no}}</a>
{% endif %}
<p
class="mx-2 p-2 border rounded border-green-500 text-green-500 hover:border-green-500 hover:text-green-500 hover:bg-white">
class="mx-2 p-2 border rounded border-blue-500 text-blue-500 hover:border-blue-500 hover:text-blue-500 hover:bg-white">
Page {{cur_page}}</p>
{% if next_page %}
<a title="Next page"
class="mx-2 p-2 border rounded bg-green-500 hover:border-green-500 hover:text-green-500 hover:bg-white"
class="mx-2 p-2 border rounded bg-blue-500 hover:border-blue-500 hover:text-blue-500 hover:bg-white"
href="{{next_page.url}}">Page {{next_page.no}}</a>
{% endif %}
</div>
Expand Down
2 changes: 0 additions & 2 deletions app/templates/js/filesaver.min.js

This file was deleted.

28 changes: 20 additions & 8 deletions app/templates/js/playlist.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
function singleItemPlaylist(file,name,basicAuth){
let hostUrl = `http://${basicAuth}${window.location.host}`
let pd = ""
pd += '#EXTM3U\n'
pd += `#EXTINF: ${name}\n`
pd += `${hostUrl}/${file}\n`
let blob = new Blob([pd], { endings: "native" });
saveAs(blob, `${name}.m3u`);
function downloadBlob(blob, filename) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}

function singleItemPlaylist(file, name, basicAuth) {
name = decodeURI(name)
let hostUrl = `http://${basicAuth}${window.location.host}`;
let pd = "";
pd += "#EXTM3U\n";
pd += `#EXTINF: ${name}\n`;
pd += `${hostUrl}/${file}\n`;
let blob = new Blob([pd], { endings: "native" });
downloadBlob(blob, `${name}.m3u`);
}
1 change: 1 addition & 0 deletions app/views/index_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ async def index(self, req: web.Request) -> web.Response:
thumbnail=f"/{alias_id}/{m.id}/thumbnail",
mime_type=m.file.mime_type,
filename=filename,
quoted_filename=quote(filename), # for playlist filename
insight=insight,
human_size=get_human_size(m.file.size),
url=f"/{alias_id}/{m.id}/view",
Expand Down
4 changes: 3 additions & 1 deletion app/views/info_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
from aiohttp import web
from telethon.tl import types
from telethon.tl.custom import Message
from jinja2 import Markup
from jinja2.utils import markupsafe

Markup = markupsafe.Markup()

from app.util import get_file_name, get_human_size
from app.config import block_downloads
Expand Down
6 changes: 3 additions & 3 deletions app/views/thumbnail_view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
from PIL import Image
import random
import io
Expand All @@ -7,7 +8,7 @@
from telethon.tl import types, custom

from .base import BaseView

from ..config import file_icon_path

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -43,8 +44,7 @@ async def thumbnail_get(self, req: web.Request) -> web.Response:
location = types.InputPhotoFileLocation

if not thumbnails:
color = tuple([random.randint(0, 255) for i in range(3)])
im = Image.new("RGB", (100, 100), color)
im = Image.open(file_icon_path)
temp = io.BytesIO()
im.save(temp, "PNG")
body = temp.getvalue()
Expand Down
14 changes: 14 additions & 0 deletions main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

module="telethon"

# Check if module is installed
if python -c "import $module" ; then
echo "Dependencies Found."
else
echo "Installing Dependencies..."
pip3 install -r requirements.txt
fi

# Run Python script
python3 run.py
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ cryptg
pillow
aiohttp_session[secure]
python-dotenv
requests
psutil
51 changes: 51 additions & 0 deletions run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os
import runpy
import requests
import time
import psutil
from dotenv import load_dotenv

load_dotenv()

APP_CMD = "python3 -m app"

def find_process_cmd(cmdline):
for proc in psutil.process_iter():
is_running = cmdline in proc.cmdline()
if(is_running):
return True

def is_alive():
repl_slug = os.environ.get("REPL_SLUG")
repl_owner = os.environ.get("REPL_OWNER")
repl_url = f"https://{repl_slug}.{repl_owner}.repl.co"
repl_url_local = "http://0.0.0.0:8080"
try:
resp = requests.get(repl_url_local, timeout=60)
except Exception as e:
print("Server response wait timed out!")
return False
return resp.ok

def run_safe():
"prevent session string from expiring due to two instances running"
try:
if not is_alive():
kill_server()
# proc = runpy.run_module('app', alter_sys=True)
if(!find_process_cmd(APP_CMD)):
# prevent running app if it is already running
print("Starting a new instance...")
os.system(APP_CMD)
else:
print("Server is already running...")
except Exception as e:
os.system("python app/generate_session_string.py")

def kill_server():
print("Killing server just incase it is not responding...")
kill_server_cmd = f"pkill -9 -f '{APP_CMD}'"
os.system(kill_server_cmd)
time.sleep(30)

run_safe()