├── .gitignore
├── LICENSE
├── README.md
├── bot.py
├── config.py
├── requirements.txt
└── src
├── airing.py
├── anime_search.py
├── dev_info.py
├── genre_results.py
├── genres.py
├── get_anime_details.py
├── get_ep_numbers.py
├── get_episode_link.py
├── get_episodes_index.py
├── inline_search.py
├── inline_search_results.py
├── instructions.py
└── start_message.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 BaraniARR
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Anime DL Telegram Bot
2 |
3 |
9 |
10 |
15 |
16 |
17 |

18 |
19 |
20 | An advanced telegram bot to get anime download links.
21 |
22 | ### How to deploy your own Anime DL Bot.
23 | ###
24 | ##### 1. Get your api_id and api_hash from [Telegram](telegram.org).
25 | ##### 2. Get your telegram bot token from [@botfather](https://t.me/botfather)
26 | ##### 3. Place the credentials in config.py
27 | ##### 4. Install the requirements using pip.
28 |
29 | ```
30 | $ pip3 install -r requirements.txt
31 | ```
32 | ###
33 | ##### 5. Run your bot by the following command
34 |
35 | ```
36 | $ python3 bot.py
37 | ```
38 | ###
39 | #### Star and Fork the Repo if you like it 💖💖
40 | ## Copyrights © 2021 BaraniARR
41 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.handlers import *
8 | from src.anime_search import anime_search
9 | from src.start_message import start_message
10 | from src.dev_info import dev_info
11 | import logging
12 | from src.genres import genres
13 | from src.genre_results import genre_results
14 | from src.get_anime_details import anime_details
15 | from src.inline_search import inline_search
16 | from src.get_episodes_index import get_epIndex
17 | from src.get_episode_link import get_ep_link
18 | from src.instructions import instructions
19 | from src.airing import airing_eps
20 | from src.inline_search_results import anime_inline_details
21 | from src.get_ep_numbers import get_ep
22 | import config
23 |
24 | # Logging is optional
25 | logging.basicConfig(
26 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
27 | )
28 | logger = logging.getLogger(__name__)
29 |
30 | # Creating a Session to activate all Handlers
31 | bot = Client(
32 | "YOUR_SESSION_NAME",
33 | api_id=config.api_id,
34 | api_hash=config.api_hash,
35 | bot_token=config.bot_token
36 | )
37 |
38 | # Adding all functions to Handlers in main() function
39 | def main():
40 | bot.add_handler(MessageHandler(anime_search, filters.regex(r'search')), group=1)
41 | bot.add_handler(MessageHandler(start_message, filters.command('start')), group=2)
42 | bot.add_handler(MessageHandler(dev_info, filters.command('info')), group=3)
43 | bot.add_handler(MessageHandler(genres, filters.command('genres')), group=4)
44 | bot.add_handler(InlineQueryHandler(inline_search), group=6)
45 | bot.add_handler(MessageHandler(airing_eps, filters.command("airing")), group=7)
46 | bot.add_handler(CallbackQueryHandler(anime_details, filters.regex('dt_*')), group=8)
47 | bot.add_handler(CallbackQueryHandler(get_epIndex, filters.regex('dl_*')), group=9)
48 | bot.add_handler(CallbackQueryHandler(get_ep_link, filters.regex('eps_*')), group=10)
49 | bot.add_handler(CallbackQueryHandler(genre_results, filters.regex('genre/')), group=11)
50 | bot.add_handler(CallbackQueryHandler(instructions, filters.regex('instructions')), group=12)
51 | bot.add_handler(MessageHandler(anime_inline_details, filters.text), group=13)
52 | bot.add_handler(CallbackQueryHandler(get_ep, filters.regex('eplink_*')), group=14)
53 |
54 | # Calling main method and handlers, polling state
55 | if __name__ == '__main__':
56 | bot.run(main())
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | """ANIME DL TELEGRAM BOT CREDENTIALS"""
7 |
8 | api_id = ""
9 | api_hash = ""
10 | bot_token = ""
11 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyrogram
2 | TgCrypto
3 | beautifulsoup4
4 | requests
5 | requests_html
6 | redis
7 |
8 |
--------------------------------------------------------------------------------
/src/airing.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from requests_html import HTMLSession
10 | from bs4 import BeautifulSoup
11 | import sys
12 |
13 | # Getting currently airing Anime from the API
14 | # Returns an "Inline Keyboard List" of Currently airing Anime
15 |
16 | def airing_eps(client, message):
17 | url = f"https://gogoanime.ai/"
18 | session = HTMLSession()
19 | response = session.get(url)
20 | response_html = response.text
21 | soup = BeautifulSoup(response_html, 'html.parser')
22 | anime = soup.find("nav", {"class": "menu_series cron"}).find("ul")
23 | air = []
24 | for link in anime.find_all('a'):
25 | airing_link = link.get('href')
26 | name = link.get('title')
27 | link = airing_link.split('/')
28 | lnk_final = link[2]
29 | res = sys.getsizeof(lnk_final)
30 | if int(res) > 64:
31 | pass
32 | else:
33 | air.append([InlineKeyboardButton(f"{name}", callback_data=f"dt_{lnk_final}")])
34 | repl = InlineKeyboardMarkup(air)
35 | message.reply_text("**Currently Airing Anime: **", reply_markup=repl, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/anime_search.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | from requests_html import HTMLSession
9 | from bs4 import BeautifulSoup
10 |
11 | # Searching anime by regex pattern "/search Anime Name"
12 |
13 | def anime_search(client, message):
14 | q = message.text
15 | q1 = q.split()
16 | q1.remove(q1[0])
17 | str = " "
18 | query = str.join(q1)
19 | if query == "":
20 | # If no query string is mentioned
21 | message.reply_animation("https://media.tenor.com/images/cfe564edcb140705ce45aeeca8183812/tenor.gif",
22 | caption=f"""**Your Query should be in This format:**
23 |
24 | `/search Name of the Anime you want to Search.`""", parse_mode="markdown")
25 | else:
26 | url = f"https://gogoanime.ai//search.html?keyword={query}"
27 | session = HTMLSession()
28 | response = session.get(url)
29 | response_html = response.text
30 | soup = BeautifulSoup(response_html, 'html.parser')
31 | animes = soup.find("ul", {"class": "items"}).find_all("li")
32 | # print(animes)
33 | keyb = []
34 | for anime in animes: # For every anime found
35 | tit = anime.a["title"]
36 | urll = anime.a["href"]
37 | r = urll.split('/')
38 | # aAnimes.append({"title" : anime.a["title"] , "link" : "https://www2.gogoanime.sh{}".format(anime.a["href"])})
39 | keyb.append([InlineKeyboardButton("{}".format(tit), callback_data="dt_{}".format(r[2]))])
40 | if keyb == []:
41 | # If returned list is empty, Send the following message.
42 | message.reply_text("No results found, Check your Spelling and Search Again...")
43 | else:
44 | rep = InlineKeyboardMarkup(keyb)
45 | message.reply_text(text=f"Your Search results for **{query}**", reply_markup=rep, parse_mode="markdown")
46 |
47 |
--------------------------------------------------------------------------------
/src/dev_info.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 |
9 | # Dev Info is Completely Optional
10 |
11 | def dev_info(client, message):
12 | keyb = [
13 | [InlineKeyboardButton("Rate me on BotsArchive", url="https://t.me/BotsArchive/1858")]
14 | ]
15 | reply_markup = InlineKeyboardMarkup(keyb)
16 | message.reply_text("""Made with ❤️ in 🇮🇳 by .
17 |
18 | Language: [Python3](https://www.python.org/)
19 |
20 | Bot Framework: [Pyrogram Asyncio](https://github.com/pyrogram/pyrogram)
21 |
22 | Server:
23 |
24 | Please share the bot if you like it 👍👍""", reply_markup=reply_markup, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/genre_results.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from bs4 import BeautifulSoup
10 | from pyrogram.errors.exceptions.bad_request_400 import ButtonDataInvalid
11 | import sys
12 |
13 | # Get Inline Keyboard List of Anime with the returned Genre Callback_Data
14 |
15 | def genre_results(client, callback_query):
16 | query = callback_query
17 | data = query.data
18 | data_pre = data.split("_")
19 | gen = data_pre[1].split("/")
20 | gen_name = gen[2]
21 | try:
22 | url = f"https://gogoanime.ai{data_pre[1]}?page={data_pre[0]}"
23 | response = requests.get(url)
24 | plainText = response.text
25 | soup = BeautifulSoup(plainText, "lxml")
26 | animes = soup.find("ul", {"class": "items"}).find_all("li")
27 | keybrd_genre_butt = []
28 | for anime in animes: # For every anime found
29 | tit = anime.a["title"]
30 | urll = anime.a["href"]
31 | r = urll.split('/')
32 | res = sys.getsizeof(r[2])
33 | if int(res) > 64:
34 | pass
35 | else:
36 | keybrd_genre_butt.append([(InlineKeyboardButton(tit, callback_data=f"dt_{r[2]}"))])
37 | # n = 3
38 | # keybrd_genre_butt = [keybrd_genre_butts[i:i + n] for i in range(0, len(keybrd_genre_butts), n)]
39 | callback_query.answer("Fetching Genres...")
40 | keybrd_genre_butt.append([InlineKeyboardButton("Back", callback_data=f"{int(data_pre[0]) - 1}_{data_pre[1]}"),
41 | (InlineKeyboardButton(f"Page {data_pre[0]}", callback_data="none")),
42 | (InlineKeyboardButton("Next", callback_data=f"{int(data_pre[0]) + 1}_{data_pre[1]}"))])
43 | reply_markup = InlineKeyboardMarkup(keybrd_genre_butt)
44 | query.edit_message_text(f"Anime under genre **{gen_name}**: ", reply_markup=reply_markup, parse_mode="markdown")
45 | except AttributeError:
46 | callback_query.answer("End of search Results...", show_alert=True)
47 |
--------------------------------------------------------------------------------
/src/genres.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from bs4 import BeautifulSoup
10 |
11 | # Lists out all Genres and related anime as callback_data
12 |
13 | def genres(client, message):
14 | gen_keyb = []
15 | animelink = 'https://gogoanime.ai/'
16 | response = requests.get(animelink)
17 | plainText = response.text
18 | soup = BeautifulSoup(plainText, "lxml")
19 | anime = soup.find("nav", {"class": "menu_series genre right"}).find("ul")
20 | for link in anime.find_all('a'):
21 | genre_link = link.get('href')
22 | # print(genre_link)
23 | name = genre_link.split('/')
24 | genre_name = name[2]
25 | gen_keyb.append((InlineKeyboardButton(genre_name, callback_data=f"1_{genre_link}")))
26 | # print(gen_keyb)
27 | n = 2
28 | keybrd_genre_butt = [gen_keyb[i:i + n] for i in range(0, len(gen_keyb), n)]
29 | #print(keybrd_genre_butt)
30 | reply_markup = InlineKeyboardMarkup(keybrd_genre_butt)
31 | message.reply_text("Choose One Genre to See anime Related to: ", reply_markup=reply_markup, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/get_anime_details.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from bs4 import BeautifulSoup
10 |
11 | # Get anime Details on anime_search callback_data
12 |
13 | def anime_details(client, callback_query):
14 | global list_more_anime
15 | query = callback_query
16 | dt = query.data
17 | dt1 = dt.split("_")
18 | data = dt1[1]
19 | query.answer("Fetching Anime Details...")
20 | animelink = 'https://gogoanime.ai/category/{}'.format(data)
21 | response = requests.get(animelink)
22 | plainText = response.text
23 | soup = BeautifulSoup(plainText, "lxml")
24 | source_url = soup.find("div", {"class": "anime_info_body_bg"}).img
25 | # url of anime image
26 | imgg = source_url.get('src')
27 | # title name of the anime
28 | tit_url = soup.find("div", {"class": "anime_info_body_bg"}).h1.string
29 | lis = soup.find_all('p', {"class": "type"})
30 | plot_sum = lis[1]
31 | pl = plot_sum.get_text().split(':')
32 | pl.remove(pl[0])
33 | sum = ""
34 | plot_summary = sum.join(pl)
35 | type_of_show = lis[0].a['title']
36 | ai = lis[2].find_all('a') # .find_all('title')
37 | # get list of genres by using genres variable
38 | genres = []
39 | for link in ai:
40 | genres.append(link.get('title'))
41 | # get released year
42 | year = lis[3].get_text()
43 | # status completed or airing,,,
44 | status = lis[4].a.get_text()
45 | # other names
46 | oth_names = lis[5].get_text()
47 | lnk = soup.find(id="episode_page")
48 | source_url = lnk.find("li").a
49 | # ending ep no
50 | try:
51 | source_url = lnk.findAll("li")
52 | for link in source_url:
53 | list_more_anime = []
54 | list_more_anime.append(link.a)
55 | ep_num = list_more_anime[0].get("ep_end")
56 | except:
57 | source_url = lnk.find("li").a
58 | ep_num = source_url.get("ep_end")
59 | kkeeyyb = [
60 | [InlineKeyboardButton("Download for Free", callback_data=f"dl_{data}")],
61 | ]
62 | reply_markup = InlineKeyboardMarkup(kkeeyyb)
63 | query.edit_message_text(f"""[{tit_url}]({imgg})
64 |
65 | **{tit_url} ({year})**
66 |
67 | **{oth_names}**
68 |
69 | **Type:** `{type_of_show}`
70 |
71 | **Status: **__{status}__
72 |
73 | **Genres: **`{genres}`
74 |
75 | **Episodes: **__{ep_num}__
76 |
77 | **Summary: **`{plot_summary}`""", reply_markup=reply_markup, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/get_ep_numbers.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from bs4 import BeautifulSoup
10 |
11 | # get episodes from specific range, specified in get_episodes_index
12 |
13 | def get_ep(client, callback_query):
14 | dataInitial = callback_query.data
15 | dataSplit = dataInitial.split("_")
16 | animeid = dataSplit[1]
17 | ep_index_num = dataSplit[2]
18 | global list_more_anime
19 | query = callback_query
20 | data = query.data
21 | query.answer("Fetching Episodes...")
22 | data_spl = data.split("_")
23 | # print(data_spl)
24 | animelink = f'https://gogoanime.ai/category/{data_spl[1]}'
25 | response = requests.get(animelink)
26 | plainText = response.text
27 | soup = BeautifulSoup(plainText, "lxml")
28 | tit_url = soup.find("div", {"class": "anime_info_body_bg"}).h1.string
29 | lnk = soup.find(id="episode_page")
30 | try:
31 | source_url = lnk.findAll("li")
32 | for link in source_url:
33 | list_more_anime = []
34 | list_more_anime.append(link.a)
35 | ep_num_tot = list_more_anime[0].get("ep_end")
36 | ep_num_tot_range = int(ep_num_tot) + 1
37 | except:
38 | source_url = lnk.find("li").a
39 | ep_num_tot = source_url.get("ep_end")
40 | ep_num_tot_range = int(ep_num_tot) + 1
41 | listInitial = []
42 | for i in range(1, ep_num_tot_range):
43 | listInitial.append(i)
44 | n = 40
45 | listOrganisedInitial = [listInitial[i:i + n] for i in range(0, len(listInitial), n)]
46 | keyb_eps = []
47 | for i in listOrganisedInitial[int(ep_index_num)]:
48 | keyb_eps.append((InlineKeyboardButton(f'{i}', callback_data=f"eps_{i}_{animeid}")))
49 | m=5
50 | keybrd_inline_butt = [keyb_eps[i:i + m] for i in range(0, len(keyb_eps), m)]
51 | keybrd_inline_butt.append([InlineKeyboardButton("◀️ Back", callback_data=f"dl_{animeid}")])
52 | reply_markups = InlineKeyboardMarkup(keybrd_inline_butt)
53 | query.edit_message_reply_markup(reply_markup=reply_markups)
--------------------------------------------------------------------------------
/src/get_episode_link.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from requests_html import HTMLSession
10 | from bs4 import BeautifulSoup
11 |
12 | # gets lists of Episdoes link when episode number and anime id is passed as callback_data
13 |
14 | def get_ep_link(client, callback_query):
15 | query = callback_query
16 | data = query.data
17 | query.answer(f"Please wait till I fetch Links...")
18 | data_spl_ep = data.split("_")
19 | ep_num_link_get = int(data_spl_ep[1])
20 | data_spl_ep.remove(data_spl_ep[0])
21 | data_spl_ep.remove(data_spl_ep[0])
22 | str_qry = ""
23 | str_qry_final = str_qry.join(data_spl_ep)
24 | # print(str_qry_final)
25 | animelink = f'https://gogoanime.ai/category/{str_qry_final}'
26 | response = requests.get(animelink)
27 | plainText = response.text
28 | soup = BeautifulSoup(plainText, "lxml")
29 | lnk = soup.find(id="episode_page")
30 | source_url = lnk.find("li").a
31 | tit_url = soup.find("div", {"class": "anime_info_body_bg"}).h1.string
32 | # print(tit_url)
33 | ep_num_tot = source_url.get("ep_end")
34 | last_ep = int(ep_num_tot)
35 | # print(last_ep)
36 | # print(ep_num_link_get)
37 | episode = ep_num_link_get
38 | # print("Generating Links from", start, "to", end)
39 | animename = animelink.split("/")
40 | URL_PATTERN = 'https://gogoanime.ai/{}-episode-{}'
41 | url = URL_PATTERN.format(str_qry_final, ep_num_link_get)
42 | srcCode = requests.get(url)
43 | plainText = srcCode.text
44 | soup = BeautifulSoup(plainText, "lxml")
45 | source_url = soup.find("li", {"class": "dowloads"}).a
46 | vidstream_link = source_url.get('href')
47 | # print(vidstream_link)
48 | URL = vidstream_link
49 | dowCode = requests.get(URL)
50 | data = dowCode.text
51 | soup = BeautifulSoup(data, "lxml")
52 | try:
53 | dow_url1 = soup.findAll('div', {'class': 'dowload'})[0].find('a')
54 | except:
55 | pass
56 | try:
57 | dow_url2 = soup.findAll('div', {'class': 'dowload'})[1].find('a')
58 | except:
59 | pass
60 | try:
61 | dow_url3 = soup.findAll('div', {'class': 'dowload'})[2].find('a')
62 | except:
63 | pass
64 | try:
65 | dow_url4 = soup.findAll('div', {'class': 'dowload'})[3].find('a')
66 | except:
67 | pass
68 | try:
69 | dow_url5 = soup.findAll('div', {'class': 'dowload'})[4].find('a')
70 | except:
71 | pass
72 | try:
73 | dow_url6 = soup.findAll('div', {'class': 'dowload'})[5].find('a')
74 | except:
75 | pass
76 | try:
77 | dow_url7 = soup.findAll('div', {'class': 'dowload'})[6].find('a')
78 | except:
79 | pass
80 |
81 | try:
82 | downlink1 = dow_url1.get('href')
83 | except:
84 | pass
85 | try:
86 | downlink2 = dow_url2.get('href')
87 | except:
88 | pass
89 | try:
90 | downlink3 = dow_url3.get('href')
91 | except:
92 | pass
93 | try:
94 | downlink4 = dow_url4.get('href')
95 | except:
96 | pass
97 | try:
98 | downlink5 = dow_url5.get('href')
99 | except:
100 | pass
101 | try:
102 | downlink6 = dow_url6.get('href')
103 | except:
104 | pass
105 | try:
106 | downlink7 = dow_url7.get('href')
107 | except:
108 | pass
109 |
110 | try:
111 | str1 = dow_url1.string
112 | str_spl1 = str1.split()
113 | str_spl1.remove(str_spl1[0])
114 | str_original_1 = ""
115 | quality_name1 = str_original_1.join(str_spl1)
116 | except:
117 | pass
118 |
119 | try:
120 | str2 = dow_url2.string
121 | str_spl2 = str2.split()
122 | str_spl2.remove(str_spl2[0])
123 | str_original_2 = ""
124 | quality_name2 = str_original_2.join(str_spl2)
125 | except:
126 | pass
127 |
128 | try:
129 | str3 = dow_url3.string
130 | str_spl3 = str3.split()
131 | str_spl3.remove(str_spl3[0])
132 | str_original_3 = ""
133 | quality_name3 = str_original_3.join(str_spl3)
134 | except:
135 | pass
136 |
137 | try:
138 | str4 = dow_url4.string
139 | str_spl4 = str4.split()
140 | str_spl4.remove(str_spl4[0])
141 | str_original_4 = ""
142 | quality_name4 = str_original_4.join(str_spl4)
143 | except:
144 | pass
145 |
146 | try:
147 | str5 = dow_url5.string
148 | str_spl5 = str5.split()
149 | str_spl5.remove(str_spl5[0])
150 | str_original_5 = ""
151 | quality_name5 = str_original_5.join(str_spl5)
152 | except:
153 | pass
154 |
155 | try:
156 | str6 = dow_url6.string
157 | str_spl6 = str6.split()
158 | str_spl6.remove(str_spl6[0])
159 | str_original_6 = ""
160 | quality_name6 = str_original_6.join(str_spl6)
161 | except:
162 | pass
163 |
164 | try:
165 | str7 = dow_url7.string
166 | str_spl7 = str7.split()
167 | str_spl7.remove(str_spl7[0])
168 | str_original_7 = ""
169 | quality_name7 = str_original_7.join(str_spl7)
170 | except:
171 | pass
172 |
173 | res_list = []
174 | try:
175 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name1}','lnk':f'{downlink1}'})
176 | except:
177 | pass
178 | try:
179 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name2}','lnk':f'{downlink2}'})
180 | except:
181 | pass
182 | try:
183 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name3}','lnk':f'{downlink3}'})
184 | except:
185 | pass
186 | try:
187 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name4}','lnk':f'{downlink4}'})
188 | except:
189 | pass
190 | try:
191 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name5}','lnk':f'{downlink5}'})
192 | except:
193 | pass
194 | try:
195 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name6}','lnk':f'{downlink6}'})
196 | except:
197 | pass
198 | try:
199 | res_list.append({'num':f'{ep_num_link_get}','qual':f'{quality_name7}','lnk':f'{downlink7}'})
200 | except:
201 | pass
202 |
203 |
204 | if ep_num_link_get == last_ep:
205 | key = []
206 | for links in res_list:
207 | ep_number = links.get('num')
208 | quality = links.get('qual')
209 | download_links = links.get('lnk')
210 | key.append((InlineKeyboardButton(f"Ep{ep_number} {quality}", url=f"{download_links}")))
211 | n = 3
212 | keys = [key[i:i + n] for i in range(0, len(key), n)]
213 | keys.append([(InlineKeyboardButton("⏪ Previous Ep", callback_data=f"eps_{ep_num_link_get - 1}_{str_qry_final}")),
214 | (InlineKeyboardButton("↔️Back to list↔️", callback_data=f"dl_{str_qry_final}"))])
215 | reply_markup = InlineKeyboardMarkup(keys)
216 | query.edit_message_text(text=f"""You are now watching **Episode {ep_num_link_get}** of **{tit_url}** :-
217 |
218 | Please share the bot if you like it ☺️.
219 |
220 | __Note: Select HDP link for faster streaming.__
221 |
222 | **This the Last Episode of the Series 🥳🥳🥳**""", reply_markup=reply_markup, parse_mode="markdown")
223 | elif ep_num_link_get == 1:
224 | key = []
225 | for links in res_list:
226 | ep_number = links.get('num')
227 | quality = links.get('qual')
228 | download_links = links.get('lnk')
229 | key.append((InlineKeyboardButton(f"Ep{ep_number} {quality}", url=f"{download_links}")))
230 | n = 3
231 | keys = [key[i:i + n] for i in range(0, len(key), n)]
232 | keys.append([(InlineKeyboardButton("↔️Back To list↔️", callback_data=f"dl_{str_qry_final}")),
233 | (InlineKeyboardButton("Next Ep ⏩", callback_data=f"eps_{ep_num_link_get + 1}_{str_qry_final}"))])
234 | reply_markup = InlineKeyboardMarkup(keys)
235 | query.edit_message_text(text=f"""You are now watching **Episode {ep_num_link_get}** of **{tit_url}** :-
236 |
237 | Please share the bot if you like it ☺️.
238 |
239 | __Note: Select HDP link for faster streaming.__""", reply_markup=reply_markup, parse_mode="markdown")
240 | else:
241 | key = []
242 | for links in res_list:
243 | ep_number = links.get('num')
244 | quality = links.get('qual')
245 | download_links = links.get('lnk')
246 | key.append((InlineKeyboardButton(f"Ep{ep_number} {quality}", url=f"{download_links}")))
247 | n = 3
248 | keys = [key[i:i + n] for i in range(0, len(key), n)]
249 | keys.append([(InlineKeyboardButton("⏪ Previous Ep", callback_data=f"eps_{ep_num_link_get - 1}_{str_qry_final}")),
250 | (InlineKeyboardButton("↔️Back To list↔️", callback_data=f"dl_{str_qry_final}")),
251 | (InlineKeyboardButton("Next Ep ⏩", callback_data=f"eps_{ep_num_link_get + 1}_{str_qry_final}"))])
252 | reply_markup = InlineKeyboardMarkup(keys)
253 | query.edit_message_text(text=f"""You are now watching **Episode {ep_num_link_get}** of **{tit_url}** :-
254 |
255 | Please share the bot if you like it ☺️.
256 |
257 | __Note: Select HDP link for faster streaming.__""", reply_markup=reply_markup, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/get_episodes_index.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from requests_html import HTMLSession
10 | from bs4 import BeautifulSoup
11 |
12 | # Splits Inline buttons into ranges of episodes when Episodes counts is greater than 120
13 |
14 | def get_epIndex(client, callback_query):
15 | global list_more_anime
16 | query = callback_query
17 | data = query.data
18 | query.answer("Fetching Episodes...")
19 | data_spl = data.split("_")
20 | # print(data_spl)
21 | animelink = f'https://gogoanime.ai/category/{data_spl[1]}'
22 | response = requests.get(animelink)
23 | plainText = response.text
24 | soup = BeautifulSoup(plainText, "lxml")
25 | tit_url = soup.find("div", {"class": "anime_info_body_bg"}).h1.string
26 | lnk = soup.find(id="episode_page")
27 | try:
28 | source_url = lnk.findAll("li")
29 | for link in source_url:
30 | list_more_anime = []
31 | list_more_anime.append(link.a)
32 | ep_num_tot = list_more_anime[0].get("ep_end")
33 | ep_num_tot_range = int(ep_num_tot) + 1
34 | if int(ep_num_tot) > 120:
35 | listInitial = []
36 | for i in range(1, ep_num_tot_range):
37 | listInitial.append(i)
38 | n = 40
39 | listOrganisedInitial = [listInitial[i:i + n] for i in range(0, len(listInitial), n)]
40 | listIndex = []
41 | for item in listOrganisedInitial:
42 | listIndex.append(
43 | (InlineKeyboardButton(f"{item[0]}-{item.pop()}",
44 | callback_data=f"eplink_{data_spl[1]}_{listOrganisedInitial.index(item)}")))
45 | o = 3
46 | listIndexFinal = [listIndex[i:i + o] for i in range(0, len(listIndex), o)]
47 | listIndexFinal.append([InlineKeyboardButton("◀️ Back", callback_data=f"dt_{data_spl[1]}")])
48 | repl = InlineKeyboardMarkup(listIndexFinal)
49 | # print(listIndex)
50 | query.edit_message_text(text=f"""You selected **{tit_url}**,
51 |
52 | Select the Episode you want :-""", reply_markup=repl, parse_mode="markdown")
53 | elif int(ep_num_tot) < 120:
54 | source_url = lnk.find("li").a
55 | ep_num_tot = source_url.get("ep_end")
56 | ep_num_tot_range = int(ep_num_tot) + 1
57 | n = 5
58 | keyb_eps = []
59 | for i in range(1, ep_num_tot_range):
60 | keyb_eps.append((InlineKeyboardButton(f'{i}', callback_data=f"eps_{i}_{data_spl[1]}")))
61 | keybrd_inline_butt = [keyb_eps[i:i + n] for i in range(0, len(keyb_eps), n)]
62 | reply_markups = InlineKeyboardMarkup(keybrd_inline_butt)
63 | query.edit_message_text(text=f"""You selected **{tit_url}**,
64 |
65 | Select the Episode you want :-""", reply_markup=reply_markups, parse_mode="markdown")
66 | except:
67 | source_url = lnk.find("li").a
68 | ep_num_tot = source_url.get("ep_end")
69 | ep_num_tot_range = int(ep_num_tot) + 1
70 | n = 5
71 | keyb_eps = []
72 | for i in range(1, ep_num_tot_range):
73 | keyb_eps.append((InlineKeyboardButton(f'{i}', callback_data=f"eps_{i}_{data_spl[1]}")))
74 | keybrd_inline_butt = [keyb_eps[i:i + n] for i in range(0, len(keyb_eps), n)]
75 | reply_markups = InlineKeyboardMarkup(keybrd_inline_butt)
76 | query.edit_message_text(text=f"""You selected **{tit_url}**,
77 |
78 | Select the Episode you want :-""", reply_markup=reply_markups, parse_mode="markdown")
--------------------------------------------------------------------------------
/src/inline_search.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from bs4 import BeautifulSoup
10 | from requests_html import HTMLSession
11 | from uuid import uuid4
12 |
13 | # Inline Anime Search
14 |
15 | def inline_search(client, inline_query):
16 | url = f"https://gogoanime.ai//search.html?keyword={inline_query.query}"
17 | session = HTMLSession()
18 | response = session.get(url)
19 | response_html = response.text
20 | soup = BeautifulSoup(response_html, 'html.parser')
21 | animes = soup.find("ul", {"class": "items"}).find_all("li")
22 | # print(animes)
23 | aAnimes = []
24 | for anime in animes: # For every anime found
25 | rel = anime.find("p", {"class": "released"}).string
26 | r = rel.split()
27 | rr = ""
28 | released_year = rr.join(r)
29 | tits = anime.a["title"]
30 | urll = anime.a["href"]
31 | imgg = anime.img["src"]
32 | ur = urll.split('/')
33 | url_of_result = ur[2]
34 | aAnimes.append(InlineQueryResultArticle(title=f"{tits}", description=f"{released_year}",
35 | input_message_content=InputTextMessageContent(f"{url_of_result}"),
36 | thumb_url=f"{imgg}"))
37 | inline_query.answer(aAnimes, cache_time=1)
--------------------------------------------------------------------------------
/src/inline_search_results.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 | import requests
9 | from requests_html import HTMLSession
10 | from bs4 import BeautifulSoup
11 |
12 | # Shows anime details on returned inline search id
13 |
14 | def anime_inline_details(client,message):
15 | try:
16 | animelink = 'https://gogoanime.ai/category/{}'.format(message.text)
17 | response = requests.get(animelink)
18 | plainText = response.text
19 | soup = BeautifulSoup(plainText, "lxml")
20 | source_url = soup.find("div", {"class": "anime_info_body_bg"}).img
21 | # url of anime image
22 | imgg = source_url.get('src')
23 | # print(imgg)
24 | # title name of the anime
25 | tit_url = soup.find("div", {"class": "anime_info_body_bg"}).h1.string
26 | # print(tit_url)
27 | lis = soup.find_all('p', {"class": "type"})
28 | plot_sum = lis[1]
29 | # print(plot_sum)
30 | pl = plot_sum.get_text().split(':')
31 | pl.remove(pl[0])
32 | sum = ""
33 | # print plot summary
34 | plot_summary = sum.join(pl)
35 | # print the type of show
36 | type_of_show = lis[0].a['title']
37 | ai = lis[2].find_all('a') # .find_all('title')
38 | # get list of genres by using genres variable
39 | genres = []
40 | for link in ai:
41 | genres.append(link.get('title'))
42 | # get released year
43 | year = lis[3].get_text()
44 | # status completed or airing,,,
45 | status = lis[4].a.get_text()
46 | # other names
47 | oth_names = lis[5].get_text()
48 | lnk = soup.find(id="episode_page")
49 | source_url = lnk.find("li").a
50 | # ending ep no
51 | ep_num = int(source_url.get("ep_end"))
52 | kkeeyyb = [
53 | [InlineKeyboardButton("Download Ad-Free", callback_data=f"dl {message.text}")],
54 | ]
55 | reply_markup = InlineKeyboardMarkup(kkeeyyb)
56 | message.reply_text(f"""[{tit_url}]({imgg})
57 |
58 | **{tit_url} ({year})**
59 |
60 | **{oth_names}**
61 |
62 | **Type: **`{type_of_show}`
63 |
64 | **Status: **`{status}`
65 |
66 | **Genres: **`{genres}`
67 |
68 | **Episodes: **`{ep_num}`
69 |
70 | **Summary: **`{plot_summary}`""", reply_markup=reply_markup, parse_mode="markdown")
71 | except:
72 | pass
--------------------------------------------------------------------------------
/src/instructions.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 |
9 | # Totally Optional
10 |
11 | def instructions(client, callback_query):
12 | query = callback_query
13 | query.answer("Please Read Carefully!!!")
14 | keyb = [
15 | [InlineKeyboardButton("Search Anime Inline", switch_inline_query_current_chat="")]
16 | ]
17 | reply_markup = InlineKeyboardMarkup(keyb)
18 | query.edit_message_caption(caption="""**This Bot can Get your favourite Anime and It provides FREE Download Link with a fastest server(Google drive). ❤️😍**
19 |
20 | **Points to Be Noted :-**
21 |
22 | __👉Since gogoanime changes their domain often, The bot will go for frequent maintenance. Don't worry, the bot will still be online during maintenance.__
23 |
24 | __👉For streaming in mobile, open the links with VLC Media Player. You can also use MX Player.__
25 |
26 | __👉For streaming in PC, use VLC media player network stream.__
27 |
28 | __👉For downloads, just open the links in a browser.__
29 |
30 | **That's it, You are all caught up, just start and enjoy your favourite anime😁😆**
31 |
32 | **Type /search to Search for an Anime...**""", parse_mode="markdown", reply_markup=reply_markup)
33 |
--------------------------------------------------------------------------------
/src/start_message.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2021 BaraniARR
2 | # Encoding = 'utf-8'
3 | # Licensed under MIT License
4 | # Special Thanks for gogoanime
5 |
6 | from pyrogram import *
7 | from pyrogram.types import *
8 |
9 | # Attractive Welcome message
10 |
11 | def start_message(client, message):
12 | kkeeyyb = [
13 | [InlineKeyboardButton("Instructions", callback_data="instructions")],
14 | ]
15 | reply_markup = InlineKeyboardMarkup(kkeeyyb)
16 | pic_url = "https://drive.google.com/file/d/1TzmuSj05qF6Sm5Z_CSm3AGUCBx4Oe0F0/view?usp=sharing"
17 | message.reply_photo(pic_url, caption=f"""**Hi {message.chat.first_name}**,
18 |
19 | Welcome to Anime DL Bot, Here you can Download all Anime for FREE 😁 ,For TG Anime Join @Anime_Collectors
20 | !!!
21 |
22 | __Please read all the instructions about the bot before surfing on...__
23 |
24 | See /whats_new to know about latest updates...""", reply_markup=reply_markup, parse_mode="markdown")
25 |
--------------------------------------------------------------------------------