├── LICENSE ├── Procfile ├── README.md ├── app.json ├── bot.py ├── commands └── __init__.py ├── config.py ├── inline └── __init__.py ├── requirements.txt └── subtitle └── __init__.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [ ★彡 Anand 彡★] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python3 bot.py 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SubtitleBot 2 | 3 | A Simple Telegram subtitle Bot Made in Python. 4 | 5 | This project was inspired by [SpecHide](https://github.com/SpecHide)'s [@GetSubtitleBot](https://telegram.dog/GetSubtitleBot) 6 | 7 | 8 | This project is not made of any api or third party applications. Bot is made by web scrapping. If you got any bugs feel free to contact me in [Our group](https://telegram.dog/KeralasBots) 9 | 10 | 11 | ### Installation 12 | 13 | #### The Easy Way 14 | 15 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?) 16 | 17 | ##### Required Variables 18 | 19 | * `BOT_TOKEN`: Create a bot using [@BotFather](https://telegram.dog/BotFather), and get the Telegram API token. 20 | 21 | ## Community 22 | 23 | - Telegram Support Chat : [@KeralasBots](https://telegram.dog/KeralasBots) 24 | - Telegram Updates Channel : [KeralaBotsNews](https://telegram.dog/KeralaBotsNews) 25 | 26 | ## Contribution 27 | 28 | Contributions are always welcome.
29 | Feel Free to contribute 😁. 30 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SubtitlesBot", 3 | "description": "A simple subtitle bot made in python. Create your Fork now.", 4 | "keywords": [ 5 | "telegram", 6 | "subtitle", 7 | "searcher", 8 | "download" 9 | ], 10 | "website": "https://github.com/Anandpskerala/SubtitlesBot", 11 | "repository": "https://github.com/Anandpskerala/SubtitlesBot", 12 | "env": { 13 | "BOT_TOKEN": { 14 | "description": "Your bot token", 15 | "value": "" 16 | } 17 | }, 18 | "addons": [], 19 | "buildpacks": [ 20 | { 21 | "url": "heroku/python" 22 | } 23 | ], 24 | "formation": { 25 | "worker": { 26 | "quantity": 1, 27 | "size": "free" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import logging 2 | logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 3 | level=logging.INFO) 4 | 5 | logger = logging.getLogger(__name__) 6 | 7 | from config import BOT_TOKEN 8 | 9 | from telegram.ext import ( 10 | Updater, 11 | CommandHandler, 12 | CallbackQueryHandler, 13 | MessageHandler, 14 | Filters, 15 | InlineQueryHandler 16 | ) 17 | 18 | from commands import ( 19 | start, 20 | searching 21 | ) 22 | 23 | from inline import( 24 | button, 25 | inlinequery 26 | ) 27 | 28 | 29 | def main(): 30 | updater = Updater(token=BOT_TOKEN, use_context=True, workers=8) 31 | logger.info(f"SUCESSFULLY STARTED THE BOT IN {updater.bot.username}") 32 | start_handler = CommandHandler('start', start) 33 | search_handler = MessageHandler(Filters.text, searching) 34 | 35 | dispatcher = updater.dispatcher 36 | dispatcher.add_handler(start_handler) 37 | dispatcher.add_handler(search_handler) 38 | dispatcher.add_handler(CallbackQueryHandler(button)) 39 | dispatcher.add_handler(InlineQueryHandler(inlinequery)) 40 | updater.start_polling() 41 | updater.idle() 42 | updater.stop() 43 | 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /commands/__init__.py: -------------------------------------------------------------------------------- 1 | from subtitle import ( 2 | BASE_URL, 3 | get_lang, 4 | search_sub 5 | ) 6 | 7 | from telegram import ( 8 | Update, 9 | InlineKeyboardButton, 10 | InlineKeyboardMarkup 11 | ) 12 | 13 | from telegram.ext import CallbackContext 14 | 15 | def start(update: Update, context: CallbackContext): 16 | context.bot.send_message(chat_id=update.effective_chat.id, text=f"Hi *{update.effective_user.first_name}*!\n\nI am subtitle downloader bot. I can provide movie subtitles.\n\n==> Just send me Movie name. Use @imdb or @imdbot inline to get currect movie name.\n\nSubscribe ℹ️ @Keralabotsnews if you ❤️ using this bot!", parse_mode="Markdown") 17 | 18 | def searching(update: Update, context: CallbackContext): 19 | if update.message.via_bot != None: 20 | return 21 | 22 | search_message = context.bot.send_message(chat_id=update.effective_chat.id, text="Searching your subtitle file") 23 | sub_name = update.effective_message.text 24 | full_index, title, keyword = search_sub(sub_name) 25 | inline_keyboard = [] 26 | if len(full_index) == 0: 27 | context.bot.edit_message_text(chat_id=update.effective_chat.id, message_id=search_message.message_id, text="No results found") 28 | return 29 | 30 | index = full_index[:15] 31 | for i in index: 32 | subtitle = title[i-1] 33 | key = keyword[i-1] 34 | inline_keyboard.append([InlineKeyboardButton(subtitle, callback_data=f"{key}")]) 35 | 36 | reply_markup = InlineKeyboardMarkup(inline_keyboard) 37 | context.bot.edit_message_text(chat_id=update.effective_chat.id, message_id=search_message.message_id, text=f"Got the following results for your query *{sub_name}*. Select the preffered type from the below options", parse_mode="Markdown", reply_markup=reply_markup) 38 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | BOT_TOKEN = os.environ.get("BOT_TOKEN") 4 | -------------------------------------------------------------------------------- /inline/__init__.py: -------------------------------------------------------------------------------- 1 | from uuid import uuid4 2 | 3 | from telegram import ( 4 | Update, 5 | InlineKeyboardButton, 6 | InlineKeyboardMarkup, 7 | InlineQueryResultArticle, 8 | InlineQueryResultDocument 9 | ) 10 | 11 | from subtitle import ( 12 | BASE_URL, 13 | get_lang, 14 | search_sub 15 | ) 16 | 17 | 18 | def button(update, context): 19 | query = update.callback_query 20 | query.answer() 21 | sub = query.data 22 | index, language, link = get_lang(sub) 23 | 24 | if len(index) == 0: 25 | query.edit_message_text(text="Something went wrong") 26 | return 27 | 28 | inline_keyboard = [] 29 | for i in range(len(index)): 30 | button_name = language[i-1] 31 | button_data = link[i-1] 32 | inline_keyboard.append([InlineKeyboardButton(f"{button_name.upper()}", switch_inline_query_current_chat=f"{button_data}")]) 33 | 34 | reply_markup = InlineKeyboardMarkup(inline_keyboard) 35 | query.edit_message_text(text="Select your language", reply_markup=reply_markup) 36 | 37 | def inlinequery(update, context): 38 | query = update.inline_query.query 39 | inline = [ 40 | [ 41 | InlineKeyboardButton("Our Group", url="https://telegram.dog/Keralasbots"), 42 | InlineKeyboardButton("Our Channel", url="https://telegram.dog/Keralabotsnews") 43 | ] 44 | ] 45 | results = [ 46 | InlineQueryResultDocument( 47 | id=uuid4(), 48 | document_url=query, 49 | title="Get the File", 50 | mime_type="application/zip", 51 | reply_markup=InlineKeyboardMarkup(inline), 52 | caption="©️ @GetSubtitles_bot\n\nUse @UnzipTGBot for unzipping this zip file or download the file and unzip manually" 53 | ) 54 | ] 55 | update.inline_query.answer(results) 56 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | bs4 2 | requests 3 | python-telegram-bot 4 | lxml 5 | -------------------------------------------------------------------------------- /subtitle/__init__.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup as bs 3 | 4 | BASE_URL = "https://isubtitles.org" 5 | 6 | def search_sub(query): 7 | r = requests.get(f"{BASE_URL}/search?kwd={query}").text 8 | soup = bs(r, "lxml") 9 | list_search = soup.find_all("div", class_="row") 10 | index = [] 11 | title = [] 12 | keywords = [] 13 | 14 | second_soup = bs(str(list_search), 'lxml') 15 | headings = second_soup.find_all("h3") 16 | 17 | third_soup = bs(str(headings), "lxml") 18 | search_links = third_soup.find_all("a") 19 | 20 | i = 0 21 | 22 | for a in search_links: 23 | key = a.get("href").split("/") 24 | if key[1] not in keywords: 25 | i += 1 26 | index.append(i) 27 | title.append(a.text) 28 | keywords.append(key[1]) 29 | 30 | return index, title, keywords 31 | 32 | 33 | def get_lang(keyword): 34 | url = f"{BASE_URL}/{keyword}" 35 | request = requests.get(url).text 36 | fourth_soup = bs(request, "lxml") 37 | filesoup = fourth_soup.find_all("table") 38 | fifth_soup = bs(str(filesoup), "lxml") 39 | table_soup = fifth_soup.find_all("a") 40 | language = [] 41 | index = [] 42 | link = [] 43 | i = 0 44 | for b in table_soup: 45 | if b["href"].startswith("/download/"): 46 | i += 1 47 | h = b.get("href").split("/") 48 | buttoname = h[3] 49 | if buttoname not in language: 50 | index.append(i) 51 | language.append(buttoname) 52 | link.append(f"{BASE_URL}{b.get('href')}") 53 | return index, language, link 54 | --------------------------------------------------------------------------------