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
__pycache__/
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_channel": true,
"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`.
@ -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`.
> * `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`.
> * `otg` - On-The-Go Indexing settings. Whether to allow indexing channels/chats other than the specified chats dynamically on the go.
* **Run app.**

View File

@ -24,10 +24,8 @@ except (KeyError, ValueError):
try:
index_settings_str = os.environ["INDEX_SETTINGS"].strip()
index_settings = json.loads(index_settings_str)
'''
{"index_all": true, "index_private":false, "index_group": false, "index_channel": true, "include_chats": [], "exclude_chats": []}
'''
otg_settings = index_settings['otg']
enable_otg = otg_settings['enable']
except:
traceback.print_exc()
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):
h = handler
client = h.client
p = r"/{chat:[^/]+}"
routes = [
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_private = index_settings['index_private']
@ -48,47 +57,21 @@ async def setup_routes(app, handler):
if chat.is_user:
if index_private:
alias_id = generate_alias_id(chat)
elif chat.is_group:
if index_group:
elif chat.is_channel:
if index_channel:
alias_id = generate_alias_id(chat)
else:
if index_channel:
if index_group:
alias_id = generate_alias_id(chat)
if not alias_id:
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}")
else:
for chat_id in include_chats:
chat = await client.get_entity(chat_id)
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}")
routes.append(web.view(r'/{wildcard:.*}', h.wildcard))
app.add_routes(routes)

View File

@ -15,6 +15,9 @@
<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>
{% if otg %}
<a title="On-The-Go Indexing" href="/otg" class="text-xl lg:text-2xl xl:text-3xl"> OTG Indexing </a>
{% endif %}
</header>

View File

@ -3,6 +3,7 @@
<h1 class=" my-2 text-2xl text-center font-bold text-green-400">
Available Sources
</h1>
<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">
{% 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 telethon.tl import types
from telethon.tl.custom import Message
from telethon.tl.types import User, Chat, Channel
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__)
@ -22,17 +23,6 @@ class Views:
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):
raise web.HTTPFound('/')
@ -41,27 +31,77 @@ class Views:
async def home(self, req):
if len(chat_ids) == 1:
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):
data = await self._home(req)
return web.json_response(data)
@aiohttp_jinja2.template('otg.html')
async def otg_view(self, req):
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')
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']
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_name = chat['title']
log_msg = ''
@ -145,7 +185,7 @@ class Views:
'cur_page' : offset_val+1,
'next_page': next_page,
'search': search_query,
'name' : chat['title'],
'name' : chat_name,
'logo': f"/{alias_id}/logo",
'title' : "Index of " + chat_name
}
@ -153,21 +193,18 @@ class Views:
@aiohttp_jinja2.template('info.html')
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"])
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']
try:
message = await self.client.get_messages(entity=chat_id, ids=file_id)
@ -248,7 +285,16 @@ class Views:
async def logo(self, req):
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_name = "Image not available"
try:
@ -305,7 +351,16 @@ class Views:
async def thumbnail_get(self, req):
file_id = int(req.match_info["id"])
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']
try:
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):
file_id = int(req.match_info["id"])
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']
try: