add otg indexing support

This commit is contained in:
odysseusmax
2020-09-20 22:08:52 +05:30
parent fe194ca9e8
commit 2fffd9353d
8 changed files with 219 additions and 128 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
.env .env
__pycache__/ __pycache__/
venv/ venv/
*.sh

View File

@ -61,7 +61,13 @@ This is the general format, change the values of corresponding fields as your re
"index_group": false, "index_group": false,
"index_channel": true, "index_channel": true,
"exclude_chats": [], "exclude_chats": [],
"include_chats": [] "include_chats": [],
"otg": {
"enable": false,
"include_private": false,
"include_group": true,
"include_channel": true
}
} }
``` ```
> * `index_all` - Whether to consider all the chats associated with the telegram account. Value should either be `true` or `false`. > * `index_all` - Whether to consider all the chats associated with the telegram account. Value should either be `true` or `false`.
@ -70,6 +76,7 @@ This is the general format, change the values of corresponding fields as your re
> * `index_channel` - Whether to index channels. Only considered if `index_all` is set to `true`. Value should either be `true` or `false`. > * `index_channel` - Whether to index channels. Only considered if `index_all` is set to `true`. Value should either be `true` or `false`.
> * `exclude_chats` - An array/list of chat id's that should be ignored for indexing. Only considered if `index_all` is set to `true`. > * `exclude_chats` - An array/list of chat id's that should be ignored for indexing. Only considered if `index_all` is set to `true`.
> * `include_chats` - An array/list of chat id's to index. Only considered if `index_all` is set to `false`. > * `include_chats` - An array/list of chat id's to index. Only considered if `index_all` is set to `false`.
> * `otg` - On-The-Go Indexing settings. Whether to allow indexing channels/chats other than the specified chats dynamically on the go.
* **Run app.** * **Run app.**

View File

@ -24,10 +24,8 @@ except (KeyError, ValueError):
try: try:
index_settings_str = os.environ["INDEX_SETTINGS"].strip() index_settings_str = os.environ["INDEX_SETTINGS"].strip()
index_settings = json.loads(index_settings_str) index_settings = json.loads(index_settings_str)
''' otg_settings = index_settings['otg']
{"index_all": true, "index_private":false, "index_group": false, "index_channel": true, "include_chats": [], "exclude_chats": []} enable_otg = otg_settings['enable']
'''
except: except:
traceback.print_exc() traceback.print_exc()
print("\n\nPlease set the INDEX_SETTINGS environment variable correctly") print("\n\nPlease set the INDEX_SETTINGS environment variable correctly")

View File

@ -29,9 +29,18 @@ def generate_alias_id(chat):
async def setup_routes(app, handler): async def setup_routes(app, handler):
h = handler h = handler
client = h.client client = h.client
p = r"/{chat:[^/]+}"
routes = [ routes = [
web.get('/', h.home), web.get('/', h.home),
web.get('/api', h.api_home), web.post('/otg', h.dynamic_view),
web.get('/otg', h.otg_view),
web.get(p, h.index),
web.get(p + r"/logo", h.logo),
web.get(p + r"/{id:\d+}/view", h.info),
web.get(p + r"/{id:\d+}/download", h.download_get),
web.head(p + r"/{id:\d+}/download", h.download_head),
web.get(p + r"/{id:\d+}/thumbnail", h.thumbnail_get),
web.view(r'/{wildcard:.*}', h.wildcard)
] ]
index_all = index_settings['index_all'] index_all = index_settings['index_all']
index_private = index_settings['index_private'] index_private = index_settings['index_private']
@ -48,47 +57,21 @@ async def setup_routes(app, handler):
if chat.is_user: if chat.is_user:
if index_private: if index_private:
alias_id = generate_alias_id(chat) alias_id = generate_alias_id(chat)
elif chat.is_group: elif chat.is_channel:
if index_group: if index_channel:
alias_id = generate_alias_id(chat) alias_id = generate_alias_id(chat)
else: else:
if index_channel: if index_group:
alias_id = generate_alias_id(chat) alias_id = generate_alias_id(chat)
if not alias_id: if not alias_id:
continue continue
p = r"/{chat:" + alias_id + "}"
p_api = '/api' + p
r = [
web.get(p, h.index),
web.get(p_api, h.api_index),
web.get(p + r"/logo", h.logo),
web.get(p + r"/{id:\d+}/view", h.info),
web.get(p_api + r"/{id:\d+}/view", h.api_info),
web.get(p + r"/{id:\d+}/download", h.download_get),
web.head(p + r"/{id:\d+}/download", h.download_head),
web.get(p + r"/{id:\d+}/thumbnail", h.thumbnail_get),
]
routes += r
log.debug(f"Index added for {chat.id} :: {chat.title} at /{alias_id}") log.debug(f"Index added for {chat.id} :: {chat.title} at /{alias_id}")
else: else:
for chat_id in include_chats: for chat_id in include_chats:
chat = await client.get_entity(chat_id) chat = await client.get_entity(chat_id)
alias_id = generate_alias_id(chat) alias_id = generate_alias_id(chat)
p = r"/{chat:" + alias_id + "}"
p_api = '/api' + p
r = [
web.get(p, h.index),
web.get(p_api, h.api_index),
web.get(p + r"/logo", h.logo),
web.get(p + r"/{id:\d+}/view", h.info),
web.get(p_api + r"/{id:\d+}/view", h.api_info),
web.get(p + r"/{id:\d+}/download", h.download_get),
web.head(p + r"/{id:\d+}/download", h.download_head),
web.get(p + r"/{id:\d+}/thumbnail", h.thumbnail_get),
]
routes += r
log.debug(f"Index added for {chat.id} :: {chat.title} at /{alias_id}") log.debug(f"Index added for {chat.id} :: {chat.title} at /{alias_id}")
routes.append(web.view(r'/{wildcard:.*}', h.wildcard))
app.add_routes(routes) app.add_routes(routes)

View File

@ -15,6 +15,9 @@
<div class="m-auto w-full xl:max-w-screen-xl min-h-screen"> <div class="m-auto w-full xl:max-w-screen-xl min-h-screen">
<header class="bg-red-600 text-white mb-2 p-4"> <header class="flex justify-between bg-red-600 text-white mb-2 p-4 w-full sticky top-0 shadow">
<a href="/" class="text-left text-xl lg:text-2xl xl:text-3xl"> Telegram Index </a> <a href="/" class="text-left text-xl lg:text-2xl xl:text-3xl"> Telegram Index </a>
{% if otg %}
<a title="On-The-Go Indexing" href="/otg" class="text-xl lg:text-2xl xl:text-3xl"> OTG Indexing </a>
{% endif %}
</header> </header>

View File

@ -3,6 +3,7 @@
<h1 class=" my-2 text-2xl text-center font-bold text-green-400"> <h1 class=" my-2 text-2xl text-center font-bold text-green-400">
Available Sources Available Sources
</h1> </h1>
<div class="mx-auto my-2 p-2 w-full"> <div class="mx-auto my-2 p-2 w-full">
<div class="block p-4 md:flex md:flex-wrap md:justify-center w-full text-center break-words"> <div class="block p-4 md:flex md:flex-wrap md:justify-center w-full text-center break-words">
{% for chat in chats %} {% for chat in chats %}

34
app/templates/otg.html Normal file
View File

@ -0,0 +1,34 @@
{% include 'header.html' %}
<h1 class="px-4 my-2 text-2xl text-center font-bold text-green-400">
On-The-Go Indexing
</h1>
<div class="px-4 mx-auto my-2">
<p class="text-center text-gray-700">
On-The-Go (OTG) Indexing. Index any public telegram channel or public telegram group on the go with it's username.
</p>
</div>
{% if error %}
<div id="alert" class="px-4 mx-auto my-2 text-center m-2 ">
<p class="text-white bg-red-500 w-auto inline-block px-4 py-2 rounded-lg"> {{error}} </p>
</div>
<script>
setTimeout(function(){
document.getElementById("alert").style.display = 'none';
}, 7000);
</script>
{% endif %}
<div class="px-4 mx-auto my-2">
<form class="my-2 text-center flex justify-center" action="/otg" method="POST">
<input class="px-4 py-2 rounded-l-full border border-r-0 border-teal-400 outline-none" type="text" name="id" placeholder="Enter username..." required>
<button class="px-4 py-2 bg-teal-400 border border-teal-400 hover:bg-white hover:text-teal-400 text-white rounded-r-full outline-none" type="submit">Get Result</button>
</form>
</div>
{% include 'footer.html' %}

View File

@ -8,9 +8,10 @@ import aiohttp_jinja2
from jinja2 import Markup from jinja2 import Markup
from telethon.tl import types from telethon.tl import types
from telethon.tl.custom import Message from telethon.tl.custom import Message
from telethon.tl.types import User, Chat, Channel
from .util import get_file_name, get_human_size from .util import get_file_name, get_human_size
from .config import index_settings, chat_ids from .config import otg_settings, chat_ids, enable_otg
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -22,17 +23,6 @@ class Views:
self.client = client self.client = client
async def _home(self, req):
chats = []
for chat in chat_ids:
chats.append({
'page_id': chat['alias_id'],
'name': chat['title'],
'url': req.rel_url.path + f"/{chat['alias_id']}"
})
return {'chats':chats}
async def wildcard(self, req): async def wildcard(self, req):
raise web.HTTPFound('/') raise web.HTTPFound('/')
@ -41,27 +31,77 @@ class Views:
async def home(self, req): async def home(self, req):
if len(chat_ids) == 1: if len(chat_ids) == 1:
raise web.HTTPFound(f"{chat_ids[0]['alias_id']}") raise web.HTTPFound(f"{chat_ids[0]['alias_id']}")
return await self._home(req)
chats = []
for chat in chat_ids:
chats.append({
'page_id': chat['alias_id'],
'name': chat['title'],
'url': req.rel_url.path + f"/{chat['alias_id']}"
})
return {'chats':chats, 'otg': enable_otg}
async def api_home(self, req): @aiohttp_jinja2.template('otg.html')
data = await self._home(req) async def otg_view(self, req):
return web.json_response(data) if not enable_otg:
raise web.HTTPFound('/')
return_data = {}
error = req.query.get('e')
if error:
return_data.update({'error': error})
return return_data
async def dynamic_view(self, req):
if not enable_otg:
raise web.HTTPFound('/')
rel_url = req.rel_url
include_private = otg_settings['include_private']
include_group = otg_settings['include_group']
include_channel = otg_settings['include_channel']
post_data = await req.post()
raw_id = post_data.get('id')
if not raw_id:
raise web.HTTPFound('/')
raw_id.replace('@', '')
try:
chat = await self.client.get_entity(raw_id)
except Exception as e:
log.debug(e, exc_info=True)
raise web.HTTPFound(rel_url.with_query({'e': f"No chat found with username {raw_id}"}))
if isinstance(chat, User) and not include_private:
raise web.HTTPFound(rel_url.with_query({'e': "Indexing private chats is not supported!!"}))
elif isinstance(chat, Channel) and not include_channel:
raise web.HTTPFound(rel_url.with_query({'e': "Indexing channels is not supported!!"}))
elif isinstance(chat, Chat) and not include_group:
raise web.HTTPFound(rel_url.with_query({'e': "Indexing group chats is not supported!!"}))
log.debug(f"chat {chat} accessed!!")
raise web.HTTPFound(f'/{chat.id}')
@aiohttp_jinja2.template('index.html') @aiohttp_jinja2.template('index.html')
async def index(self, req): async def index(self, req):
return await self._index(req)
async def api_index(self, req):
data = await self._index(req, True)
return web.json_response(data)
async def _index(self, req, api=False):
alias_id = req.match_info['chat'] alias_id = req.match_info['chat']
chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat = [i for i in chat_ids if i['alias_id'] == alias_id]
if not chat:
if not enable_otg:
raise web.HTTPFound('/')
try:
chat_id = int(alias_id)
chat_ = await self.client.get_entity(chat_id)
chat_name = chat_.title
except:
raise web.HTTPFound('/')
else:
chat = chat[0]
chat_id = chat['chat_id'] chat_id = chat['chat_id']
chat_name = chat['title'] chat_name = chat['title']
log_msg = '' log_msg = ''
@ -145,7 +185,7 @@ class Views:
'cur_page' : offset_val+1, 'cur_page' : offset_val+1,
'next_page': next_page, 'next_page': next_page,
'search': search_query, 'search': search_query,
'name' : chat['title'], 'name' : chat_name,
'logo': f"/{alias_id}/logo", 'logo': f"/{alias_id}/logo",
'title' : "Index of " + chat_name 'title' : "Index of " + chat_name
} }
@ -153,21 +193,18 @@ class Views:
@aiohttp_jinja2.template('info.html') @aiohttp_jinja2.template('info.html')
async def info(self, req): async def info(self, req):
return await self._info(req)
async def api_info(self, req):
data = await self._info(req)
if not data['found']:
return web.Response(status=404, text="404: Not Found")
return web.json_response(data)
async def _info(self, req):
file_id = int(req.match_info["id"]) file_id = int(req.match_info["id"])
alias_id = req.match_info['chat'] alias_id = req.match_info['chat']
chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat = [i for i in chat_ids if i['alias_id'] == alias_id]
if not chat:
if not enable_otg:
raise web.HTTPFound('/')
try:
chat_id = int(alias_id)
except:
raise web.HTTPFound('/')
else:
chat = chat[0]
chat_id = chat['chat_id'] chat_id = chat['chat_id']
try: try:
message = await self.client.get_messages(entity=chat_id, ids=file_id) message = await self.client.get_messages(entity=chat_id, ids=file_id)
@ -248,7 +285,16 @@ class Views:
async def logo(self, req): async def logo(self, req):
alias_id = req.match_info['chat'] alias_id = req.match_info['chat']
chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat = [i for i in chat_ids if i['alias_id'] == alias_id]
if not chat:
if not enable_otg:
return web.Response(status=403, text="403: Forbiden")
try:
chat_id = int(alias_id)
except:
return web.Response(status=403, text="403: Forbiden")
else:
chat = chat[0]
chat_id = chat['chat_id'] chat_id = chat['chat_id']
chat_name = "Image not available" chat_name = "Image not available"
try: try:
@ -305,7 +351,16 @@ class Views:
async def thumbnail_get(self, req): async def thumbnail_get(self, req):
file_id = int(req.match_info["id"]) file_id = int(req.match_info["id"])
alias_id = req.match_info['chat'] alias_id = req.match_info['chat']
chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat = [i for i in chat_ids if i['alias_id'] == alias_id]
if not chat:
if not enable_otg:
return web.Response(status=403, text="403: Forbiden")
try:
chat_id = int(alias_id)
except:
return web.Response(status=403, text="403: Forbiden")
else:
chat = chat[0]
chat_id = chat['chat_id'] chat_id = chat['chat_id']
try: try:
message = await self.client.get_messages(entity=chat_id, ids=file_id) message = await self.client.get_messages(entity=chat_id, ids=file_id)
@ -366,7 +421,16 @@ class Views:
async def handle_request(self, req, head=False): async def handle_request(self, req, head=False):
file_id = int(req.match_info["id"]) file_id = int(req.match_info["id"])
alias_id = req.match_info['chat'] alias_id = req.match_info['chat']
chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat = [i for i in chat_ids if i['alias_id'] == alias_id]
if not chat:
if not enable_otg:
return web.Response(status=403, text="403: Forbiden")
try:
chat_id = int(alias_id)
except:
return web.Response(status=403, text="403: Forbiden")
else:
chat = chat[0]
chat_id = chat['chat_id'] chat_id = chat['chat_id']
try: try: