Exemplo n.º 1
0
def zap(session, service, **kwargs):
	errormsg = None
	if service and "http" in service.toString():
		url = service.toString()
		url = url.split(":")
		if len(url) > 9:
			url = url[10]
			if YoutubeDL is not None and url.startswith("YT-DLP%3a//"):
				url = url.replace("YT-DLP%3a//", "")
				url = url.replace("%3a", ":")
				try:
					ydl = YoutubeDL({"format": "b", "no_color": True})
					result = ydl.extract_info(url, download=False)
					result = ydl.sanitize_info(result)
					if result and result.get("url"):
						url = result["url"]
						print("[ChannelSelection] zap / YoutubeDLP result url %s" % url)
						return (url, errormsg)
					else:
						errormsg = "No Link found!"
						print("[ChannelSelection] zap / YoutubeDLP no streams")
				except Exception as e:
					errormsg = str(e)
					print("[ChannelSelection] zap / YoutubeDLP failed %s" % str(e))
					pass
	return (None, errormsg)
Exemplo n.º 2
0
    def download_metadata(self, url: str, process_ie_data: bool):
        self._cache.clean()
        cache_key = f"{url}{process_ie_data}"
        cached_data = self._cache.get(cache_key)

        self._logger.debug(
            "Downloading metadata", url=url, cached=cached_data is not None
        )
        if cached_data:
            return cached_data

        options = {
            # Allow getting the _type value set to URL when passing a playlist entry
            "noplaylist": True,
            "extract_flat": False,
            # Causes ydl to return None on error
            "ignoreerrors": True,
            "quiet": True,
            "progress_hooks": [],
        }
        ydl = YoutubeDL(options)
        with ydl:
            try:
                metadata = ydl.extract_info(
                    url, download=False, process=process_ie_data
                )
                self._cache.register(cache_key, metadata)
                return metadata
            except Exception as e:
                self._logger.error("Downloading metadata error", url=url, error=e)
        return None
Exemplo n.º 3
0
    def test_nocheckcertificate(self):
        ydl = YoutubeDL({'logger': FakeLogger()})
        self.assertRaises(Exception, ydl.extract_info,
                          'https://127.0.0.1:%d/video.html' % self.port)

        ydl = YoutubeDL({'logger': FakeLogger(), 'nocheckcertificate': True})
        r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port)
        self.assertEqual(r['entries'][0]['url'],
                         'https://127.0.0.1:%d/vid.mp4' % self.port)
Exemplo n.º 4
0
    def test_unicode_path_redirection(self):
        # XXX: Python 3 http server does not allow non-ASCII header values
        if sys.version_info[0] == 3:
            return

        ydl = YoutubeDL({'logger': FakeLogger()})
        r = ydl.extract_info('http://127.0.0.1:%d/302' % self.port)
        self.assertEqual(r['entries'][0]['url'],
                         'http://127.0.0.1:%d/vid.mp4' % self.port)
Exemplo n.º 5
0
class YtDlpResolver:
    def __init__(self):
        self.ytdl = YoutubeDL(ytdl_opts)

    def get_url(self, video_id: str):
        try:
            return self.ytdl.extract_info(f'https://www.youtube.com/watch?v={video_id}', download=False)['url']
        except Exception as ex:
            raise PluginError(ex)
Exemplo n.º 6
0
 def _run_test(self, **params):
     ydl = YoutubeDL({
         'logger': FakeLogger(),
         # Disable client-side validation of unacceptable self-signed testcert.pem
         # The test is of a check on the server side, so unaffected
         'nocheckcertificate': True,
         **params,
     })
     r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port)
     self.assertEqual(r['entries'][0]['url'],
                      'https://127.0.0.1:%d/vid.mp4' % self.port)
Exemplo n.º 7
0
    def test_template(self):
        ie = yt_dlp.extractor.get_info_extractor(test_case['name'])()
        other_ies = [
            get_info_extractor(ie_key)()
            for ie_key in test_case.get('add_ie', [])
        ]
        is_playlist = any(k.startswith('playlist') for k in test_case)
        test_cases = test_case.get('playlist',
                                   [] if is_playlist else [test_case])

        def print_skipping(reason):
            print('Skipping %s: %s' % (test_case['name'], reason))

        if not ie.working():
            print_skipping('IE marked as not _WORKING')
            return

        for tc in test_cases:
            info_dict = tc.get('info_dict', {})
            if not (info_dict.get('id') and info_dict.get('ext')):
                raise Exception(
                    'Test definition incorrect. The output file cannot be known. Are both \'id\' and \'ext\' keys present?'
                )

        if 'skip' in test_case:
            print_skipping(test_case['skip'])
            return
        for other_ie in other_ies:
            if not other_ie.working():
                print_skipping('test depends on %sIE, marked as not WORKING' %
                               other_ie.ie_key())
                return

        params = get_params(test_case.get('params', {}))
        params['outtmpl'] = tname + '_' + params['outtmpl']
        if is_playlist and 'playlist' not in test_case:
            params.setdefault('extract_flat', 'in_playlist')
            params.setdefault('playlistend',
                              test_case.get('playlist_mincount'))
            params.setdefault('skip_download', True)

        ydl = YoutubeDL(params, auto_init=False)
        ydl.add_default_info_extractors()
        finished_hook_called = set()

        def _hook(status):
            if status['status'] == 'finished':
                finished_hook_called.add(status['filename'])

        ydl.add_progress_hook(_hook)
        expect_warnings(ydl, test_case.get('expected_warnings', []))

        def get_tc_filename(tc):
            return ydl.prepare_filename(tc.get('info_dict', {}))

        res_dict = None

        def try_rm_tcs_files(tcs=None):
            if tcs is None:
                tcs = test_cases
            for tc in tcs:
                tc_filename = get_tc_filename(tc)
                try_rm(tc_filename)
                try_rm(tc_filename + '.part')
                try_rm(os.path.splitext(tc_filename)[0] + '.info.json')

        try_rm_tcs_files()
        try:
            try_num = 1
            while True:
                try:
                    # We're not using .download here since that is just a shim
                    # for outside error handling, and returns the exit code
                    # instead of the result dict.
                    res_dict = ydl.extract_info(
                        test_case['url'],
                        force_generic_extractor=params.get(
                            'force_generic_extractor', False))
                except (DownloadError, ExtractorError) as err:
                    # Check if the exception is not a network related one
                    if not err.exc_info[0] in (
                            compat_urllib_error.URLError, socket.timeout,
                            UnavailableVideoError,
                            compat_http_client.BadStatusLine) or (
                                err.exc_info[0] == compat_HTTPError
                                and err.exc_info[1].code == 503):
                        raise

                    if try_num == RETRIES:
                        report_warning(
                            '%s failed due to network errors, skipping...' %
                            tname)
                        return

                    print(
                        'Retrying: {0} failed tries\n\n##########\n\n'.format(
                            try_num))

                    try_num += 1
                else:
                    break

            if is_playlist:
                self.assertTrue(
                    res_dict['_type'] in ['playlist', 'multi_video'])
                self.assertTrue('entries' in res_dict)
                expect_info_dict(self, res_dict,
                                 test_case.get('info_dict', {}))

            if 'playlist_mincount' in test_case:
                assertGreaterEqual(
                    self, len(res_dict['entries']),
                    test_case['playlist_mincount'],
                    'Expected at least %d in playlist %s, but got only %d' %
                    (test_case['playlist_mincount'], test_case['url'],
                     len(res_dict['entries'])))
            if 'playlist_count' in test_case:
                self.assertEqual(
                    len(res_dict['entries']), test_case['playlist_count'],
                    'Expected %d entries in playlist %s, but got %d.' % (
                        test_case['playlist_count'],
                        test_case['url'],
                        len(res_dict['entries']),
                    ))
            if 'playlist_duration_sum' in test_case:
                got_duration = sum(e['duration'] for e in res_dict['entries'])
                self.assertEqual(test_case['playlist_duration_sum'],
                                 got_duration)

            # Generalize both playlists and single videos to unified format for
            # simplicity
            if 'entries' not in res_dict:
                res_dict['entries'] = [res_dict]

            for tc_num, tc in enumerate(test_cases):
                tc_res_dict = res_dict['entries'][tc_num]
                # First, check test cases' data against extracted data alone
                expect_info_dict(self, tc_res_dict, tc.get('info_dict', {}))
                # Now, check downloaded file consistency
                tc_filename = get_tc_filename(tc)
                if not test_case.get('params', {}).get('skip_download', False):
                    self.assertTrue(os.path.exists(tc_filename),
                                    msg='Missing file ' + tc_filename)
                    self.assertTrue(tc_filename in finished_hook_called)
                    expected_minsize = tc.get('file_minsize', 10000)
                    if expected_minsize is not None:
                        if params.get('test'):
                            expected_minsize = max(expected_minsize, 10000)
                        got_fsize = os.path.getsize(tc_filename)
                        assertGreaterEqual(
                            self, got_fsize, expected_minsize,
                            'Expected %s to be at least %s, but it\'s only %s '
                            % (tc_filename, format_bytes(expected_minsize),
                               format_bytes(got_fsize)))
                    if 'md5' in tc:
                        md5_for_file = _file_md5(tc_filename)
                        self.assertEqual(tc['md5'], md5_for_file)
                # Finally, check test cases' data again but this time against
                # extracted data from info JSON file written during processing
                info_json_fn = os.path.splitext(tc_filename)[0] + '.info.json'
                self.assertTrue(os.path.exists(info_json_fn),
                                'Missing info file %s' % info_json_fn)
                with io.open(info_json_fn, encoding='utf-8') as infof:
                    info_dict = json.load(infof)
                expect_info_dict(self, info_dict, tc.get('info_dict', {}))
        finally:
            try_rm_tcs_files()
            if is_playlist and res_dict is not None and res_dict.get(
                    'entries'):
                # Remove all other files that may have been extracted if the
                # extractor returns full results even with extract_flat
                res_tcs = [{'info_dict': e} for e in res_dict['entries']]
                try_rm_tcs_files(res_tcs)
Exemplo n.º 8
0
async def add_to_playlist(_, message: Message):
    with suppress(MessageIdInvalid, MessageNotModified):
        admins = await get_admins(Config.CHAT)
        if Config.ADMIN_ONLY:
            if not (message.from_user is None and message.sender_chat
                    or message.from_user.id in admins):
                k = await message.reply_sticker(
                    "CAADBQADsQIAAtILIVYld1n74e3JuQI")
                await delete_messages([message, k])
                return
        type = ""
        yturl = ""
        ysearch = ""
        url = ""
        if message.command[0] == "fplay":
            if not (message.from_user is None and message.sender_chat
                    or message.from_user.id in admins):
                k = await message.reply("This command is only for admins.")
                await delete_messages([message, k])
                return
        msg = await message.reply_text("⚡️ **Checking recived input..**")
        if message.reply_to_message and message.reply_to_message.video:
            await msg.edit("⚡️ **Checking Telegram Media...**")
            type = 'video'
            m_video = message.reply_to_message.video
        elif message.reply_to_message and message.reply_to_message.document:
            await msg.edit("⚡️ **Checking Telegram Media...**")
            m_video = message.reply_to_message.document
            type = 'video'
            if not "video" in m_video.mime_type:
                return await msg.edit("The given file is invalid")
        elif message.reply_to_message and message.reply_to_message.audio:
            #if not Config.IS_VIDEO:
            #return await message.reply("Play from audio file is available only if Video Mode if turned off.\nUse /settings to configure ypur player.")
            await msg.edit("⚡️ **Checking Telegram Media...**")
            type = 'audio'
            m_video = message.reply_to_message.audio
        else:
            if message.reply_to_message and message.reply_to_message.text:
                query = message.reply_to_message.text
            elif " " in message.text:
                text = message.text.split(" ", 1)
                query = text[1]
            else:
                await msg.edit(
                    "You Didn't gave me anything to play.Reply to a video or a youtube link or a direct link."
                )
                await delete_messages([message, msg])
                return
            regex = r"^(?:https?:\/\/)?(?:www\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?"
            match = re.match(regex, query)
            if match:
                type = "youtube"
                yturl = query
            elif query.startswith("http"):
                try:
                    has_audio_ = await is_audio(query)
                except:
                    has_audio_ = False
                    LOGGER.error("Unable to get Audio properties within time.")
                if has_audio_:
                    try:
                        dur = await get_duration(query)
                    except:
                        dur = 0
                    if dur == 0:
                        await msg.edit(
                            "This is a live stream, Use /stream command.")
                        await delete_messages([message, msg])
                        return
                    type = "direct"
                    url = query
                else:
                    if is_ytdl_supported(query):
                        type = "ytdl_s"
                        url = query
                    else:
                        await msg.edit(
                            "This is an invalid link, provide me a direct link or a youtube link."
                        )
                        await delete_messages([message, msg])
                        return
            else:
                type = "query"
                ysearch = query
        if not message.from_user is None:
            user = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
            user_id = message.from_user.id
        else:
            user = "******"
            user_id = "anonymous_admin"
        now = datetime.now()
        nyav = now.strftime("%d-%m-%Y-%H:%M:%S")
        if type in ["video", "audio"]:
            if type == "audio":
                if m_video.title is None:
                    if m_video.file_name is None:
                        title_ = "Music"
                    else:
                        title_ = m_video.file_name
                else:
                    title_ = m_video.title
                if m_video.performer is not None:
                    title = f"{m_video.performer} - {title_}"
                else:
                    title = title_
                unique = f"{nyav}_{m_video.file_size}_audio"
            else:
                title = m_video.file_name
                unique = f"{nyav}_{m_video.file_size}_video"
                if Config.PTN:
                    ny = parse(title)
                    title_ = ny.get("title")
                    if title_:
                        title = title_
            file_id = m_video.file_id
            if title is None:
                title = 'Music'
            data = {1: title, 2: file_id, 3: "telegram", 4: user, 5: unique}
            if message.command[0] == "fplay":
                pla = [data] + Config.playlist
                Config.playlist = pla
            else:
                Config.playlist.append(data)
            await add_to_db_playlist(data)
            await msg.edit("Media added to playlist")
        elif type in ["youtube", "query", "ytdl_s"]:
            if type == "youtube":
                await msg.edit("⚡️ **Fetching Video From YouTube...**")
                url = yturl
            elif type == "query":
                try:
                    await msg.edit("⚡️ **Fetching Video From YouTube...**")
                    ytquery = ysearch
                    results = YoutubeSearch(ytquery, max_results=1).to_dict()
                    url = f"https://youtube.com{results[0]['url_suffix']}"
                    title = results[0]["title"][:40]
                except Exception as e:
                    await msg.edit("Song not found.\nTry inline mode..")
                    LOGGER.error(str(e), exc_info=True)
                    await delete_messages([message, msg])
                    return
            elif type == "ytdl_s":
                url = url
            else:
                return
            ydl_opts = {
                "quite": True,
                "geo-bypass": True,
                "nocheckcertificate": True
            }
            ydl = YoutubeDL(ydl_opts)
            try:
                info = ydl.extract_info(url, False)
            except Exception as e:
                LOGGER.error(e, exc_info=True)
                await msg.edit(f"YouTube Download Error ❌\nError:- {e}")
                LOGGER.error(str(e))
                await delete_messages([message, msg])
                return
            if type == "ytdl_s":
                title = "Music"
                try:
                    title = info['title']
                except:
                    pass
            else:
                title = info["title"]
                if info['duration'] is None:
                    await msg.edit(
                        "This is a live stream, Use /stream command.")
                    await delete_messages([message, msg])
                    return
            data = {
                1: title,
                2: url,
                3: "youtube",
                4: user,
                5: f"{nyav}_{user_id}"
            }
            if message.command[0] == "fplay":
                pla = [data] + Config.playlist
                Config.playlist = pla
            else:
                Config.playlist.append(data)
            await add_to_db_playlist(data)
            await msg.edit(f"[{title}]({url}) added to playist",
                           disable_web_page_preview=True)
        elif type == "direct":
            data = {
                1: "Music",
                2: url,
                3: "url",
                4: user,
                5: f"{nyav}_{user_id}"
            }
            if message.command[0] == "fplay":
                pla = [data] + Config.playlist
                Config.playlist = pla
            else:
                Config.playlist.append(data)
            await add_to_db_playlist(data)
            await msg.edit("Link added to playlist")
        if not Config.CALL_STATUS \
            and len(Config.playlist) >= 1:
            await msg.edit("Downloading and Processing...")
            await download(Config.playlist[0], msg)
            await play()
        elif (len(Config.playlist) == 1 and Config.CALL_STATUS):
            await msg.edit("Downloading and Processing...")
            await download(Config.playlist[0], msg)
            await play()
        elif message.command[0] == "fplay":
            await msg.edit("Downloading and Processing...")
            await download(Config.playlist[0], msg)
            await play()
        else:
            await send_playlist()
        await msg.delete()
        pl = await get_playlist_str()
        if message.chat.type == "private":
            await message.reply(pl,
                                reply_markup=await get_buttons(),
                                disable_web_page_preview=True)
        elif not Config.LOG_GROUP and message.chat.type == "supergroup":
            if Config.msg.get('playlist') is not None:
                await Config.msg['playlist'].delete()
            Config.msg['playlist'] = await message.reply(
                pl,
                disable_web_page_preview=True,
                reply_markup=await get_buttons())
            await delete_messages([message])
        for track in Config.playlist[:2]:
            await download(track)
Exemplo n.º 9
0
async def schedule_vc(bot, message):
    with suppress(MessageIdInvalid, MessageNotModified):
        type=""
        yturl=""
        ysearch=""
        msg = await message.reply_text("⚡️ **Checking recived input..**")
        if message.reply_to_message and message.reply_to_message.video:
            await msg.edit("⚡️ **Checking Telegram Media...**")
            type='video'
            m_video = message.reply_to_message.video       
        elif message.reply_to_message and message.reply_to_message.document:
            await msg.edit("⚡️ **Checking Telegram Media...**")
            m_video = message.reply_to_message.document
            type='video'
            if not "video" in m_video.mime_type:
                return await msg.edit("The given file is invalid")
        elif message.reply_to_message and message.reply_to_message.audio:
            #if not Config.IS_VIDEO:
                #return await message.reply("Play from audio file is available only if Video Mode if turned off.\nUse /settings to configure ypur player.")
            await msg.edit("⚡️ **Checking Telegram Media...**")
            type='audio'
            m_video = message.reply_to_message.audio       
        else:
            if message.reply_to_message and message.reply_to_message.text:
                query=message.reply_to_message.text
            elif " " in message.text:
                text = message.text.split(" ", 1)
                query = text[1]
            else:
                await msg.edit("You Didn't gave me anything to schedule. Reply to a video or a youtube link or a direct link.")
                await delete_messages([message, msg])
                return
            regex = r"^(?:https?:\/\/)?(?:www\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?"
            match = re.match(regex,query)
            if match:
                type="youtube"
                yturl=query
            elif query.startswith("http"):
                has_audio_ = await is_audio(query)
                if not has_audio_:
                    if is_ytdl_supported(query):
                        type="ytdl_s"
                        url=query
                    else:
                        await msg.edit("This is an invalid link, provide me a direct link or a youtube link.")
                        await delete_messages([message, msg])
                        return
                type="direct"
                url=query
            else:
                type="query"
                ysearch=query
        if not message.from_user is None:
            user=f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) - (Scheduled)"
            user_id = message.from_user.id
        else:
            user="******"
            user_id = "anonymous_admin"
        now = datetime.now()
        nyav = now.strftime("%d-%m-%Y-%H:%M:%S")
        if type in ["video", "audio"]:
            if type == "audio":
                if m_video.title is None:
                    if m_video.file_name is None:
                        title_ = "Music"
                    else:
                        title_ = m_video.file_name
                else:
                    title_ = m_video.title
                if m_video.performer is not None:
                    title = f"{m_video.performer} - {title_}"
                else:
                    title=title_
                unique = f"{nyav}_{m_video.file_size}_audio"
            else:
                title=m_video.file_name
                unique = f"{nyav}_{m_video.file_size}_video"
                if Config.PTN:
                    ny = parse(title)
                    title_ = ny.get("title")
                    if title_:
                        title = title_
            if title is None:
                title = 'Music'
            data={'1':title, '2':m_video.file_id, '3':"telegram", '4':user, '5':unique}
            sid=f"{message.chat.id}_{msg.message_id}"
            Config.SCHEDULED_STREAM[sid] = data
            await sync_to_db()
        elif type in ["youtube", "query", "ytdl_s"]:
            if type=="youtube":
                await msg.edit("⚡️ **Fetching Video From YouTube...**")
                url=yturl
            elif type=="query":
                try:
                    await msg.edit("⚡️ **Fetching Video From YouTube...**")
                    ytquery=ysearch
                    results = YoutubeSearch(ytquery, max_results=1).to_dict()
                    url = f"https://youtube.com{results[0]['url_suffix']}"
                    title = results[0]["title"][:40]
                except Exception as e:
                    await msg.edit(
                        "Song not found.\nTry inline mode.."
                    )
                    LOGGER.error(str(e), exc_info=True)
                    await delete_messages([message, msg])
                    return
            elif type == "ytdl_s":
                url=url
            else:
                return
            ydl_opts = {
                "quite": True,
                "geo-bypass": True,
                "nocheckcertificate": True
            }
            ydl = YoutubeDL(ydl_opts)
            try:
                info = ydl.extract_info(url, False)
            except Exception as e:
                LOGGER.error(e, exc_info=True)
                await msg.edit(
                    f"YouTube Download Error ❌\nError:- {e}"
                    )
                LOGGER.error(str(e))
                await delete_messages([message, msg])
                return
            if type == "ytdl_s":
                title = "Music"
                try:
                    title=info['title']
                except:
                    pass
            else:
                title = info["title"]
            data={'1':title, '2':url, '3':"youtube", '4':user, '5':f"{nyav}_{user_id}"}
            sid=f"{message.chat.id}_{msg.message_id}"
            Config.SCHEDULED_STREAM[sid] = data
            await sync_to_db()
        elif type == "direct":
            data={"1":"Music", '2':url, '3':"url", '4':user, '5':f"{nyav}_{user_id}"}
            sid=f"{message.chat.id}_{msg.message_id}"
            Config.SCHEDULED_STREAM[sid] = data
            await sync_to_db()
        if message.chat.type!='private' and message.from_user is None:
            await msg.edit(
                text="You cant schedule from here since you are an anonymous admin. Click the schedule button to schedule through private chat.",
                reply_markup=InlineKeyboardMarkup(
                    [
                        [
                            InlineKeyboardButton(f"Schedule", url=f"https://telegram.dog/{Config.BOT_USERNAME}?start=sch_{sid}"),
                        ]
                    ]
                ),)
            await delete_messages([message, msg])
            return
        today = datetime.now(IST)
        smonth=today.strftime("%B")
        obj = calendar.Calendar()
        thisday = today.day
        year = today.year
        month = today.month
        m=obj.monthdayscalendar(year, month)
        button=[]
        button.append([InlineKeyboardButton(text=f"{str(smonth)}  {str(year)}",callback_data=f"sch_month_choose_none_none")])
        days=["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"]
        f=[]
        for day in days:
            f.append(InlineKeyboardButton(text=f"{day}",callback_data=f"day_info_none"))
        button.append(f)
        for one in m:
            f=[]
            for d in one:
                year_=year
                if d < int(today.day):
                    year_ += 1
                if d == 0:
                    k="\u2063"   
                    d="none"   
                else:
                    k=d    
                f.append(InlineKeyboardButton(text=f"{k}",callback_data=f"sch_month_{year_}_{month}_{d}"))
            button.append(f)
        button.append([InlineKeyboardButton("Close", callback_data="schclose")])
        await msg.edit(f"Choose the day of the month you want to schedule the voicechat.\nToday is {thisday} {smonth} {year}. Chooosing a date preceeding today will be considered as next year {year+1}", reply_markup=InlineKeyboardMarkup(button))