alfem/telegram-download-daemon

problems

Closed this issue · 23 comments

Hi, I have everything configured correctly .. the program works for 80% ...

It often happens that it does not download the file, even if it says that it is in download but it does not go in download, then if I put another it remains in the queue .. this often happens.
I hope for a resolution of the problem.
Excuse my English, but I'm Italian

Hi, I have everything configured correctly .. the program works for 80% ...

It often happens that it does not download the file, even if it says that it is in download but it does not go in download, then if I put another it remains in the queue .. this often happens.
I hope for a resolution of the problem.
Excuse my English, but I'm Italian

  1. I would say to implement a delete for the active queues .. because the current one still leaves the files in the queue. this implies that if the download is blocked and I want to delete and put a new file at the download or put back the one that was blocked, it puts it in the queue because it still has the previous one that must end.

  2. Many video files if you download it says that the download starts but it is not true, and it remains hanging !!

  3. because if I use the pc I download the file without problems and with the daemon it crashes 80% of the time? it is not possible to implement a check on the status of the file and see, if the download is blocked, it automatically rechecks it to restart it?

I always have to stop the daemon and restart it to clean the thing, then use the terminal and then you lose the utility of telegram if I have to use the pc.

Thanks for everything

alfem commented

Could you please, report your operative system, python version and script output?

Could you please, report your operative system, python version and script output?

download does not start

Schermata 2021-02-21 alle 14 45 57

Schermata 2021-02-21 alle 14 45 15

alfem commented

Is that the full output? Perhaps you are not using the latest version of the script.

Is that the full output? Perhaps you are not using the latest version of the script.

`#!/usr/bin/env python3

Telegram Download Daemon

Author: Alfonso E.M. alfonso@el-magnifico.org

You need to install telethon (and cryptg to speed up downloads)

from os import getenv, rename
import subprocess
import math
import pprint

from sessionManager import getSession, saveSession

from telethon import TelegramClient, events
from telethon.tl.types import PeerChannel, DocumentAttributeFilename, DocumentAttributeVideo
import logging

logging.basicConfig(format='[%(levelname) 5s/%(asctime)s]%(name)s:%(message)s',
level=logging.WARNING)

import multiprocessing
import argparse
import asyncio

TELEGRAM_DAEMON_API_ID = "29***"
TELEGRAM_DAEMON_API_HASH = "0bff052a8f74492*******"
TELEGRAM_DAEMON_CHANNEL = "-10013*****"

TELEGRAM_DAEMON_SESSION_PATH = "/home/migliore/public_html/tlg/session/"

TELEGRAM_DAEMON_DEST="/home/migliore/public_html/tlg/downloads/"
TELEGRAM_DAEMON_TEMP="/home/migliore/public_html/tlg/temp/"

TELEGRAM_DAEMON_TEMP_SUFFIX="tdd"

parser = argparse.ArgumentParser(
description="Script to download files from Telegram Channel.")
parser.add_argument(
"--api-id",
required=TELEGRAM_DAEMON_API_ID == None,
type=int,
default=TELEGRAM_DAEMON_API_ID,
help=
'api_id from https://core.telegram.org/api/obtaining_api_id (default is TELEGRAM_DAEMON_API_ID env var)'
)
parser.add_argument(
"--api-hash",
required=TELEGRAM_DAEMON_API_HASH == None,
type=str,
default=TELEGRAM_DAEMON_API_HASH,
help=
'api_hash from https://core.telegram.org/api/obtaining_api_id (default is TELEGRAM_DAEMON_API_HASH env var)'
)
parser.add_argument(
"--dest",
type=str,
default=TELEGRAM_DAEMON_DEST,
help=
'Destination path for downloaded files (default is /telegram-downloads).')
parser.add_argument(
"--temp",
type=str,
default=TELEGRAM_DAEMON_DEST,
help=
'Destination path for temporary files (default is using the same downloaded files directory).')
parser.add_argument(
"--channel",
required=TELEGRAM_DAEMON_CHANNEL == None,
type=int,
default=TELEGRAM_DAEMON_CHANNEL,
help=
'Channel id to download from it (default is TELEGRAM_DAEMON_CHANNEL env var'
)
args = parser.parse_args()

api_id = args.api_id
api_hash = args.api_hash
channel_id = args.channel
tempFolder = "/home/migliore/public_html/tlg/temp/"
downloadFolder = "/home/migliore/public_html/tlg/downloads/"
foldercache = "/home/migliore/public_html/tlg/pycache/"
worker_count = multiprocessing.cpu_count()

if not tempFolder:
tempFolder = downloadFolder

Edit these lines:

proxy = None

End of interesting parameters

async def sendHelloMessage(client, peerChannel):
entity = await client.get_entity(peerChannel)
print("Hi! Ready for your files!")
await client.send_message(entity, "Hi! Ready for your files!")

async def log_reply(message, reply):
print(reply)
await message.edit(reply)

def getFilename(event: events.NewMessage.Event):
mediaFileName = "unknown"
for attribute in event.media.document.attributes:
if isinstance(attribute, DocumentAttributeFilename): return attribute.file_name
if isinstance(attribute, DocumentAttributeVideo): mediaFileName = event.original_update.message.message
return mediaFileName

in_progress={}

async def set_progress(filename, message, received, total):
if received >= total:
try: in_progress.pop(filename)
except: pass
return
percentage = math.trunc(received / total * 10000) / 100;

in_progress[filename] = f"{percentage} % ({received} / {total})"

if (int(percentage) % 5) == 0:
    await log_reply(message, f"{percentage} % ({received} / {total})")

with TelegramClient(getSession(), api_id, api_hash,
proxy=proxy).start() as client:

saveSession(client.session)

queue = asyncio.Queue()
peerChannel = PeerChannel(channel_id)

@client.on(events.NewMessage())
async def handler(event):

    if event.to_id != peerChannel:
        return

    print(event)

    if not event.media and event.message:
        command = event.message.message
        command = command.lower()
        output = "Unknown command"

        if command == "list":
            output = subprocess.run(["ls -l "+downloadFolder], shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,encoding="utf-8").stdout

        if command == "status":
            try:
                output = "".join([ f"{key}: {value}\n" for (key, value) in in_progress.items()])
                if output: output = "Active downloads:\n\n" + output
                else: output = "No active downloads"
            except:
                output = "Some error occured while checking the status. Retry."

        if command == "clean":
            output = "Cleaning "+tempFolder+"\n"
            output+=subprocess.run(["rm "+tempFolder+"/*."+TELEGRAM_DAEMON_TEMP_SUFFIX], shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,encoding="utf-8").stdout
            output = "Cleaning "+downloadFolder+"\n"
            output+=subprocess.run(["rm "+downloadFolder+"/*.*"], shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,encoding="utf-8").stdout


        await log_reply(event, output)

    if event.media:
        filename=getFilename(event)
        message=await event.reply(f"{filename} added to queue")
        await queue.put([event, message])


async def worker():
    while True:
        element = await queue.get()
        event=element[0]
        message=element[1]

        filename=getFilename(event)

        await log_reply(
            message,
            f"Downloading file {filename} ({event.media.document.size} bytes)"
        )

        download_callback = lambda received, total: set_progress(filename, message, received, total)


        await client.download_media(event.message, f"{tempFolder}/{filename}.{TELEGRAM_DAEMON_TEMP_SUFFIX}", progress_callback = download_callback)
        set_progress(filename, message, 100, 100)
        rename(f"{tempFolder}/{filename}.{TELEGRAM_DAEMON_TEMP_SUFFIX}", f"{downloadFolder}/{filename}")
        await log_reply(message, f"{filename} ready")

        queue.task_done()

async def start():
    tasks = []
    loop = asyncio.get_event_loop()
    for i in range(worker_count):
        task = loop.create_task(worker())
        tasks.append(task)
    await sendHelloMessage(client, peerChannel)
    await client.run_until_disconnected()
    for task in tasks:
        task.cancel()
    await asyncio.gather(*tasks, return_exceptions=True)

client.loop.run_until_complete(start())

`

alfem commented

I have just uploaded a 1.2 version with improved error control. Please, give it a try.

I have just uploaded a 1.2 version with improved error control. Please, give it a try.

it's not true that it's big .. it's 1.5913 gb

Schermata 2021-02-21 alle 16 08 35

and if I put more files in download
Schermata 2021-02-21 alle 16 14 23

alfem commented

Those seem to be limits of Telegram or the Telethon library theirselves.

alfem commented

You could try to change the line:

worker_count = multiprocessing.cpu_count()

to

worker_count = 1

You could try to change the line:

worker_count = multiprocessing.cpu_count()

to

worker_count = 1

i did, and after downloading 4 movies then it gave this error
Schermata 2021-02-21 alle 21 00 00

alfem commented

Well, I think your are overloading the Telegram flood control. Perhaps the nice message edition should be optional.

Meanwhile, you can comment out these two lines (or change the '5' to '20'), to avoid overload:

    if (int(percentage) % 5) == 0:
        await log_reply(message, progress_message)

it is not so .. I put work at 1, if I start downloading a movie at 80% it freezes, if I put 2 it could end the first but the second stops. If I do it manually from telegram with the same account I can also put 10 to download without problem.

same problem. the download after two or three files the downloads stop

Well, I think your are overloading the Telegram flood control. Perhaps the nice message edition should be optional.

Meanwhile, you can comment out these two lines (or change the '5' to '20'), to avoid overload:

    if (int(percentage) % 5) == 0:
        await log_reply(message, progress_message)

i put 20 But keep updating every second

alfem commented

Have you tried the latest version?

yes. 1.4. work perfectly. thanks

I have invited you to a coffee for your excellent work

all ok

alfem commented

I have invited you to a coffee for your excellent work

Thanks! I think this is the first appreciation coffee I have had in my entire life.

alfem commented

you should add a function that if you pass a file larger than 1.5 gb, it warns you with a message .. and does not queue it

Not a bad idea. I need to find the real limit first, as Telegram said it is 2Gb. Perhaps transmision protocol adds some extra bytes.