File-Like Objekt temporär speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
qupfer
User
Beiträge: 9
Registriert: Samstag 24. Mai 2014, 22:17

Hi,

ich versuche mich gerade an meinem ersten Skript. Dabei habe ich folgende Funktion:

Code: Alles auswählen

def getplaylist():
	ssh.connect('domain.server.de', username='user' , port=1234 , password='verysecret')
	stdin, stdout, stderr = ssh.exec_command("wget URLtoPlaylist -q -O -")
	return stdout
Die Playlist möchte ich an mehrere andere Funktionen übergeben, jedoch klappt das ganze nur ein mal. Daher möchte ich diese, solange das Skript läuft, "speichern.

Mit

Code: Alles auswählen

def printPlaylist(object):
	for line in object:
		print (line.rstrip())
bekomme ich das ganze ja in die Ausgabe geschrieben. Prinzipiell müsste ich anstelle von "print" ja nur eine geigente "schreibe-in-objekt-funktion" verwenden. Die Frage ist nur:
a) welche
b) wie :mrgreen:

NAtürlich habe ich schon google bemüht, und bin unter anderem darauf gestoßen. Aber leider bekomme ich nur die Meldung: ImportError: No module named 'StringIO'

Da das wohl an sich eine ziemlich simple Sache sein dürfte, hoffe ich auf schnelle Hilde :D
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Willkommen zu Python und im Forum!

Das ganze ist leider ziemlich duerftig: Was ist `ssh` und was wird von `ssh.exec_command` zurueckgegeben?

Unter der Annahme, dass es ein file-like ist - wie dein Titel sagt - sollte ein `object.seek(0)` als erste Zeile der `printPlaylist` Funktion ausreichen.

Ein paar Anmerkungen: `object` als Namen solltest du meiden, denn du ueberschreibst damit ein sogenanntes "built-in" (gleiches gilt fuer `file` falls du in Versuchung kommen solltest); wenn du Python 2 benutzt, solltest du die Klammern bei `print` entfernen, da es dort keine Funktion ist (anders als in Python 3); und zu guter letzt noch der Hinweis auf den PEP 8 Styleguide: http://legacy.python.org/dev/peps/pep-0008/
BlackJack

Ich vermute das mit dem `seek()` wird nicht klappen denn die Datei ist ja sehr wahrscheinlich eine Pipe wo die Standardausgabe von dem entfernt ausgeführten Programm heraus kommt.

Also ich würde die Zeilen ja einfach mit `list()` aus dem Dateiobjekt auslesen und dann die Liste mit den Zeilen weiterverarbeiten. Allerdings nur wenn man die Zeilen tatsächlich mehrfach braucht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Hi qupfer,
auf die Frage, welche "schreibe-in-objekt-funktion" Du verwenden sollst, ist eine Liste wohl das naheliegendste, zumal Du ja eine Play-List hast. Was soll die komplizierte Vorgehensweise, erst über ssh eine Verbindung zu einem Server aufzubauen und von dort aus wget aufzurufen? Warum nicht gleich eine HTTP-Verbindung von Python aus?
BlackJack

@Sirius3: Ich weiss nicht ob das hier der Grund ist, aber manchmal ist es wichtig von welcher IP aus so eine Anfrage gemacht wird. :-)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack: deshalb frag ich ja :P
qupfer
User
Beiträge: 9
Registriert: Samstag 24. Mai 2014, 22:17

Halo, also Danke erstmal an alle.

Mit der Liste klappt es wunderbar und ja, da hätte man™ auch selber drauf kommen können :oops:

Zur Frage, warum so umständlich:
SSH ist die einzige offene Verbindung zu dem Rechner übers Internet. Zumindestens soll es die einzige sein *g
Sicher hätte ich das auch über Portweiterleitung machen können und dann direkt http.
Letztendlich liegt es aber schlicht daran, dass ich nicht weiß, wie mir das Programm (tvheadend) sonst die Senderplaylist ausspuckt, die ich benötige, um die URL der Sender herauszufinden, um damit weiter zu "arbeiten".
Und leider sind die Urls nicht in der Art, dass man sie (einfach) lokal generieren könnte
(zum Beispiel: http://localhost:9981/stream/channelid/ ... DCE3CDEB79)
Mein eigentliches "Ziel" ist es dann auf dem Server ffmpeg (zum transcodieren) anzustoßen, und den Sender aus der Playlist zu wählen und an einen Player wie vlc/ffplay zu übergeben.
Habe das ganze ja als "Batch" Skript mit Nutzung externer Tools, aber da es noch weiter wachsen soll und ggf. ne GUI und was weiß ich nicht alles, wollte ich es in einer anderen Sprache (darf man Batch als Sprache bezeichnen?^^) neu schreiben.

Aber aktuell hänge ich an der "PIPE" und werde wohl einen Thread eröffnen. :D

Edit: ich sehe gerade, das ich aus "optischen" Gründen, die URL gekürzt hatte. Ich denke mal, hätte man gleich "localhost" gesehen, wär das Vorgehen ein klein wenig einleuchtender gewesen. Was natürlich nicht bedeutet, dass es jetzt einleuchtend ist.
BlackJack

@qupfer: Wenn man nicht Code/Kommandos/Programme auf die andere Seite übertragen möchte sondern das so programmieren möchte als *könnte* man direkt auf den Port zugreifen, würde ich wahrscheinlich einen SSH-Tunnel für den Port einrichten. So dass Anfragen an localhost:5678 (willkürliche Portnummer) auf dem Client an localhost:9981 auf dem Server gehen. Ob das auch einfach mit Paramiko einzurichten geht weiss ich allerdings nicht, ich hätte es wahrscheinlich einfach ausserhalb des Programms gemacht.
qupfer
User
Beiträge: 9
Registriert: Samstag 24. Mai 2014, 22:17

Hi,

ja wie gesagt. Die "Playlist" ist nur mittel zum Zweck. Direkter Zugriff auf den Port würde mir nicht viel bringen, da dort die TV-Anwendung läuft, die nur die originalen DVB-Transportstreams streamen kann. Das schafft aber unser Upload nicht. Daher greife ich die "lokal" ab und verwende die Streams als Input für ffmpeg. Die Frage ist dann halt noch, wie das komprimierte Video zu mir auf den Rechner kommt. Da gibt es viele Wege. direkt auf der Kommandozeile war es am einfachsten, das via Pipe zu übergeben. Daher kam ich auf die Idee, das auch so umsetzen zu wollen. Natürlich kann ffmpeg auch udp/tcp irgendwe hin schicken bzw. auf einen Port lauschen, denn man via Portweiterleitung erreichen kann.....man könnte auch ein CGI Skript (z.B in Python^^) schreiben, was das gewünschte macht....das ganze ist auch eher als "Grundlagen Python lernen" zu sehen. Ich meine, ich habe gestern zum ersten mal Python gesehen und bin eigentlich recht froh, dass das im wesentlichen jetzt läuft.
Jetzt fehlt nur noch "Optimierungen" wie einstellbare Einstellungen, ggf. eine settings.txt und solche Sachen. Aber das gröbste läuft.
Also Skript starten, Sendernamen eingeben, aus Trefferliste exakten Sender wählen und ein transkodiertes Live-Fernsehen erscheint auf meinen Desktop. Gerade zur WM ganz nett, wo da die offiziellen Livestreams gerne mal leicht überlastet sind. Auch ist das Bild trotz der relativ geringen Bitrate und Baselineprofil besser als das, was der hiesige analoge Kabelanschluss hergibt. Und die Senderauswahl ist besser

Edit: Sorry für die vielen Tipp/Rechtschreibfehler. Geht gerade nicht besser :(
Antworten