Seite 4 von 9
Re: Labeldruck und was draus folgt
Verfasst: Mittwoch 25. März 2020, 22:19
von theoS
Hab nun Zeit gehabt, den Code durchzuschauen. So ganz erschließt sich der Vorteil von map() für mich nicht. Hab gelesen, dass das elegant sein soll, aber den Vorteil daraus? Ist für mich eher verwirrend als logisch.
Aber egal, das funktioniert, und da es elegant sein soll, warum nicht? Wieder was neues kennengelernt.
Den Logger heb ich mir für später auf, der ist mir ein wenig zu redselig. Ich brauch ja nur immer das Zwischenergbnis für mich, dass ich weiß was der Code da tut.
Aber ich sehe schon, dass das noch nützlich werden kann...
Danke für die Tipps!
Den Teil des Codes habe ich nun in mein USB-Überwachungsteil eingebaut, das jetzt so wie ich es jetzt hab, die beiden Dateiinhalte austauscht, wie es das soll.
Gibt bestimmt was zu verbessern.

)
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pathlib import Path
import pyudev
import time
import pathlib
from datetime import datetime as DateTime
###---------------------------------------------------
PFAD = Path.home() / ".DruckData"
##ABFRAGE_FILENAME = PFAD / "TB_Ausgabe_Abfrage8StueckII.txt"
##ZAEHLER_FILENAME = PFAD / "numbers.csv"
###----------------------------------------------------
MEDIA_PFAD = Path('/media/earl/')
WECHSEL_DATEI_NAMEN = ["numbers.csv", "TB_Ausgabe_8iii.txt"]
print(MEDIA_PFAD)
context = pyudev.Context()
def usb_ansteckerkenner():
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block')
for device in iter(monitor.poll, None):
if 'ID_FS_TYPE' in device: ###
print(device.action)
if device.action == 'add':
name_of_stick = Path(device.get('ID_FS_LABEL'))
print(name_of_stick)
time.sleep(2)
return name_of_stick
####--------------------------------------------------------------------#####
def copy(source_path, destination_path):
try:
text = source_path.read_text(encoding="utf-8")
destination_path.write_text(text, encoding="utf-8")
except FileNotFoundError as error:
print(error)
####--------------------------------------------------------------------#####
def datei_auf_stick(name_of_stick, dateipfad, timestamp):
copy(
PFAD / dateipfad,
MEDIA_PFAD
/ name_of_stick
/ dateipfad.with_name(
f"{dateipfad.stem}_{timestamp:%Y-%m-%d_%H_%M}.csv"
),
)
####--------------------------------------------------------------------#####
def datei_auf_arbeitsverzeichnis(name_of_stick, dateipfad):
copy(MEDIA_PFAD / name_of_stick / dateipfad, PFAD / dateipfad)
####--------------------------------------------------------------------#####
def main():
timestamp = DateTime.now()
name_of_stick = usb_ansteckerkenner()
for dateiname in map(Path, WECHSEL_DATEI_NAMEN):
datei_auf_stick(name_of_stick, dateiname, timestamp)
datei_auf_arbeitsverzeichnis(name_of_stick, dateiname)
if __name__ == "__main__":
main()
Nächster Schritt: Fehlerabfangen...
Wenn die Datei nicht da ist, soll da eine kleine Box aufgehen, die knapp drüber informiert, dass da mit den Dateien was nicht passt.
Die Box soll über den Knöpfen des anderen Codeteils liegen und nichts anderes machen als den stick zu unmounten.
Grübel...
Re: Labeldruck und was draus folgt
Verfasst: Mittwoch 25. März 2020, 22:33
von Sirius3
Da hat es jetzt noch so Zeilen mit vielen Minuszeichen, die den Lesefluß stören. Funktionen trennt man mit zwei Leerzeilen.
Re: Labeldruck und was draus folgt
Verfasst: Mittwoch 25. März 2020, 22:34
von theoS
Danke, die kommen noch raus, das brauch ich im Moment noch um die Trennung zu sehen.
Bin schon ein alter Mann

Re: Labeldruck und was draus folgt
Verfasst: Mittwoch 25. März 2020, 22:59
von theoS
Zum Auswerfen des Sticks kann ich so was verwenden.
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pathlib import Path
import subprocess
MEDIA_PFAD = Path("/media/earl/")
def main():
vpath = MEDIA_PFAD / "SEAGULL"
print(vpath)
cmd = 'umount ' + str(vpath)
print(cmd)
subprocess.Popen(str(cmd), shell=True, stdout=subprocess.PIPE)
if __name__ == "__main__":
main()
wobei mich da irritiert, dass ich das Path-Objekt in einen String umwandeln muss, aber das muss wohl so sein weil ich das ja an die Shell durchreiche.
Gibts da noch was besseres?
Re: Labeldruck und was draus folgt
Verfasst: Mittwoch 25. März 2020, 23:23
von __deets__
Ja, subprocess ohne Shell=True und mit einer Liste statt einem String - dann muss auch kein path konvertiert werden.
Re: Labeldruck und was draus folgt
Verfasst: Donnerstag 26. März 2020, 08:32
von Sirius3
statt `Popen` benutzt man `run` und statt `shell=True` eine Liste.
Code: Alles auswählen
MEDIA_PFAD = Path("/media/earl/")
def main():
umount_result = subprocess.run(["umount", MEDIA_PFAD / "SEAGULL"], check=True, stdout=subprocess.PIPE)
print(umount_result.stdout)
if __name__ == "__main__":
main()
Re: Labeldruck und was draus folgt
Verfasst: Donnerstag 26. März 2020, 20:22
von theoS
OK, danke. Das funktioniert.
Hab das jetzt in die USB-Ansteckgeschichte oben eingebaut, der Stick wir ausgehängt, allerdings stoppt dann das ganze Programm. Klar, krieg ich hier eine Fehlermeldung weil die Datei nicht da ist, aber das Programm stoppt jetzt auch bei Erfolg.
Das ist doof.
Muss man das so machen wie bei der tkinter-Oberfläche? mit root.mainloop()?
Dann würde das funktionieren wenn ich die Teile dann mit der grafischen Oberfläche vereine?
Dann noch eine Frage.
Bin von VBA das so gewohnt, dass wenn ich eine Variable hab, die ich so oft in gleicher Weise brauch wie hier den name_of_stick, dann deklariere ich den Global und kann dann in jedem Modul drauf zugreifen. Soll schlechter Stil sein, aber wäre das hier nicht geschickter als die x Übergaben? (man wird in VBA zum Faulpelz erzogen...)
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pathlib import Path
import pyudev
import time
#import pathlib
from datetime import datetime as DateTime
import subprocess
PFAD = Path.home() / ".DruckData"
###----wird später gebraucht------
##ABFRAGE_FILENAME = PFAD / "TB_Ausgabe_Abfrage8StueckII.txt"
##ZAEHLER_FILENAME = PFAD / "numbers.csv"
###------------------------------
MEDIA_PFAD = Path('/media/earl/')
WECHSEL_DATEI_NAMEN = ["numbers.csv", "TB_Ausgabe_8iii.txt"]
print(MEDIA_PFAD)
context = pyudev.Context()
def usb_ansteckerkenner():
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block')
for device in iter(monitor.poll, None):
if 'ID_FS_TYPE' in device: ###
print(device.action)
if device.action == 'add':
name_of_stick = Path(device.get('ID_FS_LABEL'))
print(name_of_stick)
time.sleep(2)
return name_of_stick
def copy(name_of_stick, source_path, destination_path ):
try:
text = source_path.read_text(encoding="utf-8")
destination_path.write_text(text, encoding="utf-8")
except FileNotFoundError as error:
rauswerfer(name_of_stick)
print(error)
def datei_auf_stick(name_of_stick, dateipfad, timestamp):
copy(name_of_stick,
PFAD / dateipfad,
MEDIA_PFAD
/ name_of_stick
/ dateipfad.with_name(
f"{dateipfad.stem}_{timestamp:%Y-%m-%d_%H_%M}.csv"
),
)
def datei_auf_arbeitsverzeichnis(name_of_stick, dateipfad):
copy(name_of_stick, MEDIA_PFAD / name_of_stick / dateipfad, PFAD / dateipfad)
def rauswerfer(name_of_stick):
print(name_of_stick)
umount_result = subprocess.run(["umount", MEDIA_PFAD / name_of_stick], check=True, stdout=subprocess.PIPE)
print(umount_result.stdout)
def main():
timestamp = DateTime.now()
name_of_stick = usb_ansteckerkenner()
for dateiname in map(Path, WECHSEL_DATEI_NAMEN):
datei_auf_stick(name_of_stick, dateiname, timestamp)
datei_auf_arbeitsverzeichnis(name_of_stick, dateiname)
if __name__ == "__main__":
main()
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 11:14
von theoS
Gut, ich habe jetzt mal was probiert, das scheint zu funktionieren.
Dachte mir, wenn das dann in der Fehlerbehandlung abbricht, rufe ich einfach die main() noch mal auf, dann läuft die wieder...
Also meinen "rauswerfer" eine Zeile dazu.
Code: Alles auswählen
def rauswerfer(name_of_stick):
print(name_of_stick)
umount_result = subprocess.run(["umount", MEDIA_PFAD / name_of_stick], check=True, stdout=subprocess.PIPE)
print(umount_result.stdout)
main()
Das geht, aber ob das so gut ist?
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 11:30
von Sirius3
Das ist nicht gut. Ich weiß auch gar nicht genau, was denn Dein Problem mit dem Code oben ist. Du hast gar keine Schleife, also kann das auch nicht dauerhaft laufen.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 11:54
von theoS
Das läuft sonst weiter, wenn kein Fehler auftritt. Die Überwachung des USB läuft auch wenn das kopieren klappt. Nur wenn ein Fehler auftritt geht das nicht mehr weiter. Wenn ich main aufrufe danach geht's weiter
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 11:59
von __deets__
Das ist wirklich wirklich nicht richtig. main sollte genau *einmal* aufgerufen werden. Und in main sollten Dinge stehen, die man auch garantiert nur einmal machen will und kann. Wenn nicht, dann hast du da noch Code an anderen Stellen rumfliegen, wo er nicht hingehoert. Edit: (Wie waere es mal mit einem Gesamtbild, nicht nur Ausschnitten?) - hast du ja geliefert, ich schaue mir das mal an.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 12:04
von __deets__
So, das ist ja auch kein Wunder, dass main wieder aufrufen das Problem loest. Man muss etwas, dass man andauernd machen will, auch andauernd machen. Nicht nur einmal, und sich dann rekursiv selbst aufrufen. So in etwa:
Code: Alles auswählen
from pathlib import Path
import pyudev
import time
#import pathlib
from datetime import datetime as DateTime
import subprocess
PFAD = Path.home() / ".DruckData"
###----wird später gebraucht------
##ABFRAGE_FILENAME = PFAD / "TB_Ausgabe_Abfrage8StueckII.txt"
##ZAEHLER_FILENAME = PFAD / "numbers.csv"
###------------------------------
MEDIA_PFAD = Path('/media/earl/')
WECHSEL_DATEI_NAMEN = ["numbers.csv", "TB_Ausgabe_8iii.txt"]
print(MEDIA_PFAD)
def usb_ansteckerkenner(context):
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block')
for device in iter(monitor.poll, None):
if 'ID_FS_TYPE' in device: ###
print(device.action)
if device.action == 'add':
name_of_stick = Path(device.get('ID_FS_LABEL'))
print(name_of_stick)
time.sleep(2)
return name_of_stick
def copy(name_of_stick, source_path, destination_path ):
try:
text = source_path.read_text(encoding="utf-8")
destination_path.write_text(text, encoding="utf-8")
except FileNotFoundError as error:
rauswerfer(name_of_stick)
print(error)
def datei_auf_stick(name_of_stick, dateipfad, timestamp):
copy(name_of_stick,
PFAD / dateipfad,
MEDIA_PFAD
/ name_of_stick
/ dateipfad.with_name(
f"{dateipfad.stem}_{timestamp:%Y-%m-%d_%H_%M}.csv"
),
)
def datei_auf_arbeitsverzeichnis(name_of_stick, dateipfad):
copy(name_of_stick, MEDIA_PFAD / name_of_stick / dateipfad, PFAD / dateipfad)
def rauswerfer(name_of_stick):
print(name_of_stick)
umount_result = subprocess.run(["umount", MEDIA_PFAD / name_of_stick], check=True, stdout=subprocess.PIPE)
print(umount_result.stdout)
def main():
context = pyudev.Context()
while True:
timestamp = DateTime.now()
name_of_stick = usb_ansteckerkenner(context)
for dateiname in map(Path, WECHSEL_DATEI_NAMEN):
datei_auf_stick(name_of_stick, dateiname, timestamp)
datei_auf_arbeitsverzeichnis(name_of_stick, dateiname)
if __name__ == "__main__":
main()
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 13:06
von theoS
Muss ich mal ausprobieren. Komisch ist dann aber, dass das mit dem überwachen vom USB port funktioniert. Das läuft weiter wenn ich den Stick einstecke und auswerfe, wird mir das beim nächsten Einstecken wieder angezeigt. Das läuft also doch weiter, sonst würde das doch nur einmal angezeigt.
Das mit der Schleife ist sicher sicherer, oder? Also lag ich mit meiner Annahme so “eine Art root.mainloop()“ gar nicht so verkehrt.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 13:24
von __deets__
Was du mit dem weiterlaufen meinst weiss ich nicht. Bezueglich des "sicherer" - jein. Es ist richtiger. Oder besser "nicht falsch". Denn man benutzt in Python keine Rekursion fuer Schleifen, und vor allem ist der Programmfluss bei deiner "Loesung" kompletter Wahnsinn, und nie wieder zu verstehen. Falls man ihn je verstanden hat.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 13:36
von theoS
Mit weiter laufen meine ich, dass das Progg immer erkennt ob ein Stick eingesteckt wird oder nicht.
Wenn die Dateien dann da sind, klappt das hin und herkopieren einwandfrei. Vereinfacht, wenn ich mir nur die Aktion anzeigen lasse, kann ich den Stick 100 mal rein und wieder rausmachen, es wird immer die Aktion angezeigt.
Daraus schließe ich nach wie vor, dass das Programm “weiterläuft“.
Da es stoppt, wenn ein Fehler kommt bin ich halt auf die Idee gekommenen das Ganze neu zu starten. Für mich ist das schon logisch, ahnte aber dass das sicher wieder nicht pythonlike ist.
Oder wo anders Murks erzeugt.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 16:15
von theoS
@__deets__ Leider geht das so nicht.
Wieder kommt die Fehlermeldung und Schluss ist mit dem Programm. Das, und dann noch auf 2 verschiedene Weisen.
Also, Fall 1, numbers.csv ist auf Stick vorhanden, TB_Ausgabe_8ii.txt fehlt:
Code: Alles auswählen
================= RESTART: /home/earl/projekt/USB/usb.iix.py =================
/media/earl
add
SEAGULL
SEAGULL
b''
[Errno 2] No such file or directory: '/media/earl/SEAGULL/TB_Ausgabe_8iii.txt'
remove
Der Code stoppt aber hier, sprich, ich kann den Stick rein oder raus nehmen, egal, es kommt keine Reaktion mehr. (add oder remove sollte ja in jedem Fall so angezeigt werden wenn sich da was tut)
Dann der Fall, wenn die numbers.csv einen anderen Namen hat, die zweite Datei aber da ist:
Code: Alles auswählen
================= RESTART: /home/earl/projekt/USB/usb.iix.py =================
/media/earl
add
SEAGULL
SEAGULL
b''
[Errno 2] No such file or directory: '/media/earl/SEAGULL/numbers.csv'
SEAGULL
Traceback (most recent call last):
File "/home/earl/projekt/USB/usb.iix.py", line 38, in copy
destination_path.write_text(text, encoding="utf-8")
File "/usr/lib/python3.6/pathlib.py", line 1215, in write_text
with self.open(mode='w', encoding=encoding, errors=errors) as f:
File "/usr/lib/python3.6/pathlib.py", line 1183, in open
opener=self._opener)
File "/usr/lib/python3.6/pathlib.py", line 1037, in _opener
return self._accessor.open(self, flags, mode)
File "/usr/lib/python3.6/pathlib.py", line 387, in wrapped
return strfunc(str(pathobj), *args)
FileNotFoundError: [Errno 2] No such file or directory: '/media/earl/SEAGULL/TB_Ausgabe_8iii_2020-03-29_17_08.csv'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/earl/projekt/USB/usb.iix.py", line 79, in <module>
main()
File "/home/earl/projekt/USB/usb.iix.py", line 74, in main
datei_auf_stick(name_of_stick, dateiname, timestamp)
File "/home/earl/projekt/USB/usb.iix.py", line 50, in datei_auf_stick
f"{dateipfad.stem}_{timestamp:%Y-%m-%d_%H_%M}.csv"
File "/home/earl/projekt/USB/usb.iix.py", line 40, in copy
rauswerfer(name_of_stick)
File "/home/earl/projekt/USB/usb.iix.py", line 62, in rauswerfer
umount_result = subprocess.run(["umount", MEDIA_PFAD / name_of_stick], check=True, stdout=subprocess.PIPE)
File "/usr/lib/python3.6/subprocess.py", line 438, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['umount', PosixPath('/media/earl/SEAGULL')]' returned non-zero exit status 1.
>>>
Hier versucht das Programm dann, wenn ich das so richtig lese, den Stick z um zweiten Mal auszuhängen, was natürlich nicht geht.
In beiden Fällen geht es aber danach nicht mehr weiter. Sprich, das Prog stoppt komplett.
Wie soll ich das nu wieder lösen?
Wenn ich main() nicht mehr aufrufen darf, das auslagern in eine eigene Funktion?
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 16:24
von Sirius3
Du hast hier eine Exception, die Du abfangen mußt, und dann sinnvoll drauf reagieren.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 17:02
von theoS
@Sirius3
Yep, das weiß ich. Mein Problem: Wie?
Es muss ja so sein, dass es egal ist, welche Exception da ist. Der Stick soll ausgehängt werden und das Programm weiterlaufen. Die erste Exception wird aber schon durch das Aushängen erledigt, also gibts dann logischerweise eine zweite die aus dem Fehlen des Sticks erzeugt wird.
Selbst wenn ich beides irgendwie abfange, geht das so nicht weiter, denn dieses Teil hier: context = pyudev.Context() wird ja nicht mehr ausgeführt.
Das ist das was ich immer meine mit "das Programm bleibt stehen.
Durch das, dass ich das Ding aus main() übergebe, ist es ja, wenn ich main nicht noch mal starte nicht da.
Meine Idee dazu: Ich mache das Ding global. Dann ist es immer da, wie es ja auch sein soll.
Schlechte Idee?
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 17:13
von Sirius3
Es zeigt sich hier, dass keine gute Idee ist, wenn eine Datei nicht gefunden wurde, zu vermuten, dass es dann sinnvoll sein kann, umount aufzurufen.
Natürlich kannst Du einfach check=False setzen, dann ignorierst Du den nächsten Fehler, bis wieder etwas passiert, was Du nicht verstehst, und dann ignorierst Du das wieder, bis Du ein Programm hast, das nur deshalb „funktioniert“, weil Du einen Fehler nach dem anderen ignorierst.
Re: Labeldruck und was draus folgt
Verfasst: Sonntag 29. März 2020, 17:28
von theoS
Es zeigt sich hier, dass keine gute Idee ist, wenn eine Datei nicht gefunden wurde, zu vermuten, dass es dann sinnvoll sein kann, umount aufzurufen.
Das ist jetzt schön einfach dahingesagt. Was hast du denn alternativ für eine Idee?
Wenn eine der Dateien nicht drauf ist, soll das Programm eigentlich nichts anderes mehr tun als:
1. Den Stick auszuwerfen
2. Den Rest, insbesondere das darauf Warten, dass die neuen Dateien kommen, weiter auszuführen.
Das Programm kopiert frisch und fröhlich die Dateien die da sind - soll es eigentlich auch schon nicht, aber ist egal - und bei der Ausnahme die entsteht weil eine Datei nicht da ist, bricht es, wenn ich die so abfange wie vorgeschlagen die weitere Ausführung komplett ab.
Mir fehlt da jetzt die Phantasie, das noch irgendwie auszuwerten und dann von Fehler zu Fehler zu kommen den ich dann doch nicht vorhersehen kann um dann festzustellen: Ich als armes Programm hab jetzt tausend Sachen probiert, kann leider nicht alles tun, also werfe ich den Stick aus.
Da war meine Überlegung: Fehlt was, passiert (außer einer Meldung die noch zu machen ist) nichts anderes als dass der Stick ausgeworfen wird. Das Andere läuft inzwischen weiter, und zwar auch dann, wenn die Dateien da sind.
Wie soll ich das veranstalten?