Seite 1 von 1

Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 1. Oktober 2021, 11:25
von Fimbur
Guten Tag,
ich komme mit meinem Script leider nicht weiter, deswegen bitte ich Euch um Hilfe.
Meine Probleme stehen in den #TODO.
Der Code ist bestimmt nicht perfekt/schön. Bitte deswegen etwas Rücksicht nehmen.Danke.

Hier mein Code:

Code: Alles auswählen

import os
import telegram_send as tg

user_pfad = ("")#Zwischen den "" Pfad eingeben.
telegram_api = ("")#Zwischen den "" API Key eingeben.


def upload_log():
    upload_log = open("upload-log.txt", "a")#.txt wird erstellt.
    daten_namen = os.listdir(user_pfad)
    daten_namen.sort()
    for log_schreiben in daten_namen:
        upload_log.write(log_schreiben + "\n")
#TODO Keine doppelten Einträge schreiben, wenn das Script erneut ausgeführt wird.

def bot_upload():
    #TODO Die Datein, welche in den angegebenen Pfad gefunden wurden, mit dem erstellten Telgram Bot hochladen.

Bin dankbar für jede Hilfe.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 1. Oktober 2021, 11:34
von Sirius3
Ich nehme mal Rücksicht darauf, dass der Code nicht perfekt/schön ist, und merke alle Unschönheiten an:
Benutze keine kryptischen Abkürzungen, `tg` ist auf alle Fälle zu nichtssagend. Was auch immer telegram_send ist, ist ist bestimmt nicht der Name eines Moduls, sondern eher der einer Funktion.
Die Klammern um die "" sind unsinnig. Konstanten schreibt man komplett GROSS, also USER_PFAD, TELEGRAM_API.
Dateien öffnet man immer mit dem with-Statement, dann wird sie auch wieder sicher geschlossen, was beim Schreiben in eine Datei sehr wichtig ist.

Code: Alles auswählen

import os
import telegram_send # besserer Name für das Modul nötig

USER_PFAD = ""
TELEGRAM_API = ""

def upload_log():
    dateinamen = sorted(os.listdir(USER_PFAD))
    with open("upload-log.txt", "a", encoding="utf8") as upload_log:
        for dateiname in dateinamen:
            upload_log.write(dateiname  + "\n")
Wenn Du nicht willst, dass Einträge doppelt sind, mußt Du die Datei vorher laden und alle Dateinamen, die schon in der Datei stehen, entfernen.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 1. Oktober 2021, 17:29
von Fimbur
Ich danke Dir. Habe den Code angepasst

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Samstag 2. Oktober 2021, 08:46
von Fimbur

Code: Alles auswählen

DATUM = date.today().strftime("%d.%m.%Y %H:%M:%S")
Kann mir bitte Jemand sagen, wieso die Uhrzeit nur 0:0:0 zurück gibt?

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Samstag 2. Oktober 2021, 09:51
von __deets__
Weil date das Datum ist. Das hat keine Uhrzeit. Es gibt aber in dem Modul ein anderen Typen, der beides repräsentiert.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Samstag 2. Oktober 2021, 11:08
von Fimbur
Danke habe das richtige Modul gefunden.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Sonntag 10. Oktober 2021, 09:01
von Fimbur
Hänge Seit Tagen an diesem Problem, dass ich es nicht hinbekomme, den Ordnerinhalt zu löschen.
Mein aktueller Versuch sieht so aus:

Code: Alles auswählen

def files_loeschen():
    entfernen = os.listdir(USER_PFAD)
    for loeschen in entfernen:
        os.remove(loeschen)

files_loeschen()
Kann mir bitte Jemand sagen wo der Fehler ist?

Danke!

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Sonntag 10. Oktober 2021, 10:03
von __deets__
Listdir liefert nur den Namen. Nicht den vollen Pfad. Den musst du wahlweise zusammen bauen, oder gleich besser die pathlib benutzen, die das vereinfachen sollte.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Sonntag 10. Oktober 2021, 10:05
von rogerb
@Fimbur,

listdir() gibt die Dateinamen innerhalb eines Verzeichnisses wieder:
https://docs.python.org/3/library/os.html#os.listdir

Mit den Namen alleine kann die remove() Funktion aber nichts anfangen. Denn die erwartet den gesamten Pfad:
https://docs.python.org/3/library/os.html#os.remove

Du must also den gesamten Pfad der zu löschenden Dateien angeben. Zum Beispiel mit os.path.join()

Code: Alles auswählen

def files_loeschen():
    entfernen = os.listdir(USER_PFAD)
    for loeschen in entfernen:
        os.remove(os.path.join(USER_PFAD, loeschen))
Aber mit dem modernen pathlib Paket kann man das eigentlich schöner hinbekommen:

Code: Alles auswählen

import pathlib

USER_PATH = pathlib.Path(r"C:\temp")


def delete_files(path):
    for dir_item in path.iterdir():
        dir_item.unlink()


delete_files(USER_PATH)
https://docs.python.org/3/library/pathl ... -os-module

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Sonntag 10. Oktober 2021, 12:14
von Fimbur
Ich Danke Dir. Werde ich mir naher mal dran setzen und versuchen das umzusetzen.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Mittwoch 20. Oktober 2021, 16:09
von Fimbur
Habe mein erstes Programm nun beendet. Lauft auch gut. Noch nicht zu 100% so, wie ich es gerne hätte, aber bin schon etwas stolz.

Code ist bestimmt noch verbesserbar.

Hier der Code:

Code: Alles auswählen

import os
from posixpath import join
import requests
from datetime import datetime
from telegram import Update, update
from telegram.ext import Updater, dispatcher

USER_PFAD = "" 
TELEGRAM_Token = "" 
CHAT_ID = "" 
DATUM = datetime.today().strftime("{%d.%m.%Y-%H:%M:%S}") 

def upload_log():
    dateinamen = sorted(os.listdir(USER_PFAD)) 
    with open("upload-log.txt", "a", encoding="utf8") as upload_log: 
        for log_schreiben in dateinamen: 
            upload_log.write(os.path.join(log_schreiben, DATUM, "\n"))
            

def files_loeschen():
    entfernen = os.listdir(USER_PFAD)
    for loeschen in entfernen:
        os.remove(os.path.join(USER_PFAD, loeschen))


def telegram_bot():
    hochladen = sorted(os.listdir(USER_PFAD))
    updater = Updater(TELEGRAM_Token, use_context=True)
    dispatcher = updater.dispatcher
    bot = dispatcher.get_instance().bot
    for tg_upload in hochladen:
        upload_pfad = os.path.join(USER_PFAD, tg_upload)
        bot.send_document(CHAT_ID, open(upload_pfad, "rb"))
        

#upload_log()

#telegram_bot()

#files_loeschen()

Die ganzen imports müssen bestimmt nicht sein. Werde mich damit mal mehr beschäftigen.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Mittwoch 20. Oktober 2021, 18:52
von __blackjack__
@Fimbur: `requests`, `join()` aus `posixpath`, `Updater` und `update` aus `telegram`, und `dispatcher` aus `telegram.ext` werden in der Tat importiert, aber nicht verwendet.

Bei `TELEGRAM_Token` sollte das `Token` auch gross geschrieben sein.

`DATUM` ist keine Konstante. Da wird ins Protokoll dann immer der Zeitpunkt geschrieben an dem das Modul importiert wurde. Da sollte doch wohl aber der jeweils aktuelle Zeitpunkt beim Schreiben der Log-Nachricht stehen.

`upload_log` wird in der Funktion `upload_log()` als Name für ein Dateiobjekt verwendet. Das ist verwirrend.

`log_schreiben` klingt nach einem Funktionsnamen und nicht nach dem Namen an den ein Dateiname gebunden ist.

Was Du da in die Datei schreibst ist komisch. Du hast da etwas das `dateinamen` heisst, und Du hängst mit `os.path.join()` da weitere Pfadteile an. Dann können das aber keine Dateinamen sein, sondern müssen Verzeichnisnamen sein. Und das wird auch nirgends geprüft, ob das tatsächlich Verzeichnisnamen sind und das Sinn macht.

Durch das "\n", das auch per `os.path.join()` ans Ende angehängt wird, endet der Pfad unnötigerweise mit einem Pfadtrenner, und das ist auch für den Leser verwirrend, denn das "\n" gehört ja gar nicht zum Pfad, sondern soll als Zeilentrenner für die Datei hinzugefügt werden. Dann sollte man auch sicherstellen, dass das nirgends im Pfad-/Dateinamen davor vorkommen kann, denn sonst ist diese Datei kaputt.

Bei `files_loeschen()` ist `entfernen` wieder ein komischer falscher Name für Datei- und Verzeichnisnamen. Das löschen berücksichtigt keine Fehler, beispielsweise kann man ja nur leere Verzeichnisse auf diese Art löschen.

`hochladen` ist dann wieder so ein komischer Name für Datei- und Verzeichnisnamen. Diesmal sollten besser nur Dateinamen enthalten sein, denn nur die kann man mit `open()` öffnen. Was mich jetzt total verwirrt, denn bei `upload_log()` durften nur Dateinamen und keine Verzeichnisse in dem `USER_PFAD`-Verzeichnis liegen damit der Sinn macht. Was denn nun?

Die Datei die da versendet wird, wird geöffnet, aber nicht wieder explizit geschlossen. Das ist unsauber.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import os
from datetime import datetime

from telegram.ext import Updater

USER_PFAD = ""
TELEGRAM_TOKEN = ""
CHAT_ID = ""


def upload_log():
    zeitstempeltext = datetime.today().strftime("{%d.%m.%Y-%H:%M:%S}")
    verzeichnisnamen = sorted(
        name
        for name in os.listdir(USER_PFAD)
        if os.path.isdir(os.path.join(USER_PFAD, name))
    )
    with open("upload-log.txt", "a", encoding="utf8") as log_datei:
        for verzeichnisname in verzeichnisnamen:
            if "\n" in verzeichnisname:
                raise ValueError(
                    f"line-ending in directory name {verzeichnisname!r}"
                )

            log_datei.write(
                os.path.join(verzeichnisname, zeitstempeltext) + "\n"
            )


def files_loeschen():
    #
    # TODO Reagiert nicht sinnvoll auf Fehler beim löschen, sondern bricht die
    #   Schleife dann einfach ab.
    # 
    for name in os.listdir(USER_PFAD):
        os.remove(os.path.join(USER_PFAD, name))


def telegram_bot():
    dateinamen = sorted(
        name
        for name in os.listdir(USER_PFAD)
        if os.path.isfile(os.path.join(USER_PFAD, name))
    )
    bot = (
        Updater(TELEGRAM_TOKEN, use_context=True).dispatcher.get_instance().bot
    )
    for dateiname in dateinamen:
        with open(os.path.join(USER_PFAD, dateiname), "rb") as datei:
            bot.send_document(CHAT_ID, datei)


# upload_log()

# telegram_bot()

# files_loeschen()
Was ich da als nächstes angehen würde, ist den ganzen `os.path`-Kram durch `pathlib.Path` zu ersetzen.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Mittwoch 20. Oktober 2021, 20:44
von Fimbur
Ganz schön viel Kritik. Bin jetzt weniger stolz 🤣. Werde ich mich wohl nochmal dran setzen.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 29. Oktober 2021, 07:42
von Fimbur
Guten Morgen,
ich brauche bitte erneut Eure Hilfe.

Was ich umsetzten möchte, steht in den Code Kommentaren.
Ich verwende "os" weil ich damit besser zurecht komme.

Code: Alles auswählen

import os
from telegram.ext import *

USER_PFAD = "/home/mein-name/test/"
TELEGRAM_API_KEY = ""
CHAT_ID = ""

def lokal_files_entfernen():
    #TODO Prüfen ob Ordner nicht leer ist
    #TODO Zählen wie viele Files im Ordner sind
    #TODO Wenn Ordner == False ist, zum Anfang der Funktion springen
    
    if os.path.isdir(USER_PFAD) == True:
        auflisten = os.listdir(USER_PFAD) 
        for entfernen in auflisten:
            os.remove(os.path.join(USER_PFAD, entfernen ))
    else:
        input("Bitte Pfad zum Ordner angeben: ")

lokal_files_entfernen()
Bin dankbar für jede Antwort.

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 29. Oktober 2021, 08:55
von Sirius3
Man vergleicht nicht explizit auf True, weil das doch nur wieder den selben Wahrheitswert liefert.
os ist wirklich sehr low-level. Pathlib bietet die schönere Schnittstelle, wo man weniger Fehler machen kann.

Code: Alles auswählen

from pathlib import Path

USER_PFAD = "/home/mein-name/test/"

def lokal_files_entfernen(pfad):
    pfad = Path(pfad)
    if pfad.is_dir():
        for zu_entferenden_datei in pfad.iterdir():
            # TODO: prüfen, ob das eine Datei ist
            zu_entferenden_datei.unlink()

lokal_files_entfernen(USER_PFAD)
Zum Entfernen aller Dateien muß man nicht prüfen, ob der Ordner leer ist, und auch nicht, zählen, wie viele Dateien da sind.
Warum brauchst Du diese Information?

Wenn man etwas wiederholen will, benutzt man eine Schleife. Diese Schleife wäre ist außerhalb von lokal_files_entfernen, nämlich so lange zu fragen, bis ein Pfad eingegeben wurde:

Code: Alles auswählen

pfad = USER_PFAD
while True:
    if Path(pfad).is_dir():
        break
    pfad = input("Bitte Pfad zum Ordner angeben: ")

Re: Bitte um Hilfe bei einem Telegram Bot

Verfasst: Freitag 29. Oktober 2021, 17:28
von Fimbur
Sirius3 hat geschrieben: Freitag 29. Oktober 2021, 08:55 Man vergleicht nicht explizit auf True, weil das doch nur wieder den selben Wahrheitswert liefert.
os ist wirklich sehr low-level. Pathlib bietet die schönere Schnittstelle, wo man weniger Fehler machen kann.

Code: Alles auswählen

from pathlib import Path

USER_PFAD = "/home/mein-name/test/"

def lokal_files_entfernen(pfad):
    pfad = Path(pfad)
    if pfad.is_dir():
        for zu_entferenden_datei in pfad.iterdir():
            # TODO: prüfen, ob das eine Datei ist
            zu_entferenden_datei.unlink()

lokal_files_entfernen(USER_PFAD)
Zum Entfernen aller Dateien muß man nicht prüfen, ob der Ordner leer ist, und auch nicht, zählen, wie viele Dateien da sind.
Warum brauchst Du diese Information?

Ich möchte wissen ob in den Ordner mehr als 5000 Files liegen und wenn dem so ist entsprechend handeln.

Wenn man etwas wiederholen will, benutzt man eine Schleife. Diese Schleife wäre ist außerhalb von lokal_files_entfernen, nämlich so lange zu fragen, bis ein Pfad eingegeben wurde:

Code: Alles auswählen

pfad = USER_PFAD
while True:
    if Path(pfad).is_dir():
        break
    pfad = input("Bitte Pfad zum Ordner angeben: ")
[/quote]

Danke Für deine Antwort.