2017-07-23 10:17:25 +02:00
import os
import logging
from glob import glob
2017-08-07 22:26:25 +02:00
from subprocess import Popen , PIPE
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
from telegram import InlineKeyboardButton , InlineKeyboardMarkup
from telegram . ext import ( Updater , CommandHandler , CallbackQueryHandler ,
MessageHandler , Filters )
2017-08-06 15:49:22 +02:00
2017-08-06 15:04:48 +02:00
from vid_utils import check_dimension
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
logging . basicConfig ( format = ' %(asctime)s - %(name)s - %(levelname)s - %(message)s ' ,
level = logging . INFO )
2017-07-23 10:17:25 +02:00
logger = logging . getLogger ( __name__ )
2017-08-07 22:26:25 +02:00
#TODO I don't like these global vars...
formats = [ ] # aviable format of the video
link = ' ' #link of the video
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
def generate_keyboard ( l ) :
""" return a keyboard fom list l """
kb = [ ]
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
for code , extension , resolution in l :
kb . append ( [ InlineKeyboardButton ( " {0} , {1} " . format ( extension , resolution ) ,
callback_data = code ) ] )
return kb
def get_format ( bot , update ) :
global link
link = update . message . text # saving link in global var
formats [ : ] = [ ] # remove old formats
for f in glob ( ' *.mp4* ' ) + glob ( ' *.webm* ' ) : # with glob it is not possible check multiple extension in one regex
2017-07-23 10:17:25 +02:00
os . remove ( f ) # remove old video(s)
2017-08-07 22:26:25 +02:00
2017-07-23 10:17:25 +02:00
try :
2017-08-07 22:26:25 +02:00
"""
p = subprocess . Popen ( " youtube-dl -F {} " . format ( update . message . text ) , shell = True , stdout = subprocess . PIPE ) # this line can be very dangerous, there is a serious command-injection problem
p = p . communicate ( )
"""
cmd = " youtube-dl -F {} " . format ( update . message . text ) # this line can be very dangerous, there is a serious command-injection problem
p = Popen ( cmd , shell = True , stdout = PIPE , stderr = PIPE )
p = p . communicate ( )
it = iter ( str ( p [ 0 ] , ' utf-8 ' ) . split ( ' \n ' ) )
while not " code extension " in next ( it ) : # Remove garbage lines, i need only the formats
pass
while True : # save the formats in the formats list
try :
line = next ( it )
2017-08-08 08:20:46 +02:00
if not line : # the last line usually is empty...
2017-08-07 22:26:25 +02:00
raise StopIteration
2017-08-08 08:20:46 +02:00
if " video only " in line : # video without audio... why?
continue
2017-08-07 22:26:25 +02:00
except StopIteration :
break
else :
format_code , extension , resolution , * _ = line . strip ( ) . split ( )
formats . append ( [ format_code , extension , resolution ] )
2017-07-23 10:17:25 +02:00
except Exception as e :
2017-08-06 15:04:48 +02:00
bot . sendMessage ( chat_id = update . message . chat_id , text = ' Error: {} ' . format ( e ) )
2017-07-23 10:17:25 +02:00
logger . info ( e )
2017-08-07 22:26:25 +02:00
raise e
else :
reply_markup = InlineKeyboardMarkup ( generate_keyboard ( formats ) )
update . message . reply_text ( ' Choose format: ' , reply_markup = reply_markup )
def download_choosen_format ( bot , update ) :
query = update . callback_query
bot . edit_message_text ( text = " Downloading... " ,
chat_id = query . message . chat_id ,
message_id = query . message . message_id )
os . system ( " youtube-dl -f {0} {1} " . format ( query . data , link ) )
for f in glob ( ' *.mp4* ' ) + glob ( ' *.webm* ' ) :
check_dimension ( f )
break # check first file
for f in glob ( ' *.mp4* ' ) + glob ( ' *.webm* ' ) : # send document(s)
bot . send_document ( chat_id = query . message . chat_id , document = open ( f , ' rb ' ) )
updater = Updater ( token = INSERT_YOUR_TOKEN_HERE )
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
updater . dispatcher . add_handler ( MessageHandler ( Filters . text , get_format ) )
updater . dispatcher . add_handler ( CallbackQueryHandler ( download_choosen_format ) )
2017-07-23 10:17:25 +02:00
2017-08-07 22:26:25 +02:00
# Start the Bot
2017-07-23 10:17:25 +02:00
updater . start_polling ( )
updater . idle ( )