pdf in browser öffnen das in anderem Verzeichnis steht

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
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

Hallo Zusammen

Als Python Greenhorn werde ich mir Mühe geben meine Frage/Problem so weit ich mir vorstellen kann, möglichst detailliert zu definieren. Kann aber aus Unwissenheit sein dass ich nicht alle nötigen Infos eingepackt habe.

Ich bin dabei mit Python 2.6.6 auf Debian Squeeze und apache eine webseite zu erstellen.

Dafür habe ich das Verzeichnis "/opt/reporting/htdocs/reporting" als web start-Verzeichnis definiert. Darin auch eine datei "index.py" plaziert die mir ein pdf generiert und im Verzechnis "/opt/reporting/htdocs/reporting/pdf_reports" ablegt.

Nun möchte ich nach dem Abspeichern der pdf Datei, dass ein neuer tab im web-browser geöffnet wird und die pdf Datei angezeigt wird. Dafür habe ich den Befehl "webbrowser.open" gefunden, aber mit dem relative Pfad scheitert es.

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-

pdf_report_path="/opt/reporting/htdocs/pdf_reports/"
report_list_path="/opt/reporting/htdocs/report_list/"

from mod_python import apache,util
import sys, os, pprint
from lib import *
import defaults, config, htmllib, pickle, webbrowser
from urlparse import urlparse

sys.path.append("/usr/share/pyshared/jasperclient")
from jasperclient import JasperClient

def handler ( request ):

    url = 'http://10.10.100.10:8080/jasperserver/services/repository?wsdl'
    j = JasperClient(url,'jasperadmin','jasperadmin')
    report_list = j.listReports(dir="")
    report_list = j.listReports("/reports/samples")
    f = file(report_list_path+'reportList.txt','w')
    pickle.dump(report_list, f)
    f.close()

    url = 'http://10.10.100.10:8080/jasperserver/services/repository?wsdl'
    j = JasperClient(url,'jasperadmin','jasperadmin')
    ret = j.runReport("/reports/samples/AllAccounts","PDF")
    f = file(pdf_report_path+'AllAccounts.pdf','w')
    f.write(ret['data'])
    f.close()

    webbrowser.open("./pdf_reports/AllAccounts.pdf",2,)

    request.content_type = 'text/html'
    request.write ( "<html>" )
    request.write ( "<head>" )
    request.write ( "<title>Text Document</title>" )
    request.write ( "</head>" )
    request.write ( "<body bgcolor='#D2D2D2'>" )
    request.write ( "<table align='center' bgcolor='#000000' cellspacing='1px' cellpadding='5px' width='60%'>" )
    request.write ( "<tr><td bgcolor='#FFFFFF' align='center'>" )
    request.write ( "REPORTING" )
    request.write ( "</td></tr>" )
    request.write ( "</table>" )
    request.write ( "</body>" )
    request.write ( "</html>" )
    return apache.OK
Wie kann ich angeben, dass die zu öffnende Datei im Verzeichnis "reporting" abgelegt ist ???
Ich auf den Befehl "webbrowser.open("./pdf_reports/AllAccounts.pdf",2,)" die Fehlermeldung im apache error_log
"w3m: Can't load ./pdf_reports/AllAccounts.pdf." bekommen. Auch andere Versuche scheiterten.

Die Datei kann ich mit manuell eingetragenem Pfad im web-browser ansehen.

Gibt es für Aufrufe von Dateien in anderen Verzeichnissen und den Wechsel in andere Verzeichnisse irgendwie ein Konzept oder bewährtes Verfahren ???

Ich hoffe, dass es irgendwie relativ (zB. zum Webseiten Startverzeichnis) und ohne absoluten Pfad, wie "http://www.testseite.com/reporting/pfd_ ... counts.pdf" gehen sollte. Oder irre ich mich ???
Nur da stehe ich auf dem Schlauch.

Vielen Dank für Eure Anworten
Stefano
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

läuft deine Anwendungen serverseitig? Dann kannst du so wie so auf dem Client keinen Browser öffnen.

mod_python ist übrigens quasi tot und veraltet. Nimm' lieber den akutellen Standard WSGI und ein schickes kleines Framework wir Bottle oder Flask.

Gruß, noisefloor
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

Hallo noisfloor

Vielen Dank für deine Antwort.

Der Code ist auf dem server, wenn der Benutzer die Seite startet wird er ausgeführt.

Meine Idee ist, dass python eine web-Seite erstellt, über die der Benutzer einen Report auswählen kann, über einen button zum Beispiel. Der ausgwählte Report wird dann server-seitig erstellt, in einem Server-Verzeichnis abgelegt und schlussendlich client-seitig in einem neuen browser-tab dargestellt.

Anhand dieser Definition, ist dies wohl eher ein Problem welchen html code ich über python erstellen lasse, der dann client-seitig läuft. Richtig ???

Hast du eine Idee wie ich das mit den relativen Pfaden lösen kann ?
Ich habe ein Verzeichnis "reporting/htodcs" als start Verzeichnis für apache definiert. (apache conf : Alias /reporting /opt/reporting/htdocs).
Wenn ich wie oben beschrieben, eine Datei von einem anderen Verzeichnis anzeigen oder ausführen möchte, muss ich ja irgendwie den Pfad zum diesem Verzeichnis angeben. Wie kann ich dies in python realisieren, dass schlussendlich client-seitig in das richtige Verzeichnis gewechselt werden kann ?

Als Beispiel:
- Benutzer öffnet web-seite mit "http://10.10.100.10/reporting".
- Wechsel auf "http://10.10.100.10/reporting/pdf_reports".

Ich habe mod_python benutzt da ich eigentlich ein add-on an eine bestehende Applikation schreibe und es dort schon benutzt wird. Da werde ich wohl oder übel Zeit für WSGI investieren dürfen, bin dann aber "state of the art", hoffentlich.

Danke
Stefano
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du kannst doch per MIME-TYPE auch andere Dinge an einen Client senden, als eine HTML-Datei; also z.B. Bilder. Das sollte doch auch mit einem PDF funktionieren; dann liegt es am Client, ob er diese Datei nur speichern will oder sie mit einem PDF-Betrachter direkt anzeigen kann.

Du solltest Dir vielleicht mal ein WSGI basiertes Framework angucken, wie etwa Django. Soll es leichtgewichtig sein, dann kämen auch noch Flask oder Bottle in Frage.

Sofern die bereits bestehende Applikation nicht notwendiger Weise mit dem neuen Script verquickt werden soll, lohnt sich der Umstieg sowieso. Ist eine Verquickung notwendig, so lohnt es sich auf jeden Fall mal den Umstieg auf Django und Konsorten zu erwägen und zu evaluieren.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

Vielen Dank.
Wieder einmal mehr bewiesen: Die halbe Lösung ist, wenn man das Problem genau definieren kann.

Nein, meine Lösung wird/kann als selbstständige web-site laufen.
Ob es mögliche Nebenwirkungen geben kann, wenn WSGI und mod_python auf ein und demselben Server benutzt werden, ist mir unklar.
Denke aber positiv und hoffe mal dass es keine geben wird.

Na, da werde ich mich mal in Flask bzw. Bottle einlesen.

Danke
Stefano
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

der Weg zur Lösung ist eigentlich ganz einfach:

Man erstellt ein Skript, welches ein PDF "on the fly" baut und bindet das Skript über ein WSGI Framework an eine Route oder, wenn du bei CGI bleiben willst, an eine URL (was am Ende das gleich ist ;-) ). Das PDF lieferst du dann mit dem MIME-Typ "application/pdf" aus; dann hängt es von der Einstellung des Browsers ab, ob er es öffnet oder speichern will.

Sofern die PDF dynamisch generiert (ist bei dir wohl so?) brauchst du die nicht auf HD speichern, sondern schreibst das PDF in ein StringIO (bzw. cStringIO) Objekt, was rein im Speicher gehalten wird und nach dem Ausliefern an den Browser auf vom Garbage Collector wieder gelöscht wird. Vorteil: kein I/O mit der Festplatte, kein händisches Aufräumen notwendig.

Gruß, noisefloor
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

On the fly mag ich, weil eben kein nachträgliches aufräumen nötig ist.

Bin dabei mich in WSGI und flask einzuarbeiten, dies wird einen Moment benötigen. :shock:

Vielen Dank für die rasche und kompetente Unterstützung.
Höchstwahrscheinlich ist das nicht der letze thread von mir. :lol:

Gruss, Stefano
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Bei Verwendung von Flask dürfte es eigentlich keinen Grund mehr geben, noch irgendwo "rohes" WSGI benutzen zu müssen. Zum Herausgeben von Dateien siehe flask.send_file(), welches auch mit dateiartigen Objekten, wie `StringIO()` sie erzeugt, klarkommen müsste. Achte nur darauf, dass in diesem Fall kein Dateiname besteht und du den Mime-Type somit besser selbst festlegen solltest. Es ist zumindest nicht dokumentiert, wie das Raten des Mime-Types vonstatten geht. Ich würde dann davon ausgehen, dass es auf der Dateiendung beruht.

EDIT: Im Docstring sehe ich gerade, dass das Mimetype-Guessing ohnehin inzwischen als deprecated eingestuft wurde.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

also ich mache es mit Bottle so wie oben beschrieben.

Wobei ich direkt

Code: Alles auswählen

return buf.read()
machen (buf ist das StringIO Objekt, welches das PDF enthält) und vorher noch den Content-type im Response-Header auf "application/pdf" setzt. Als statische Datei funktioniert das zumindest mit Bottle IMHO nicht, weil man einen Root-Pfad angeben muss - und den hat das StringIO Objekt nicht.

Gruß, noisefloor
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

Na, da habe ich mich auf etwas eingelassen. :shock: :?: :?: :?:

Ich "arbeite" mich aktuell in Flask ein, komme mir aber vor wie der Esel vor dem Berge.
Zum Glück ist die Dokumentation sehr gut, mit Beispielen und detaillierten Erklärungen.
Happy RTFM.

Vielen Dank an Alle, wird sicher nicht der letzte Thread meinerseits sein.

Werden in diesem Forum geschlossene Threads als solche gekennzeichnet und wenn ja wie ??

Gruss
Stefano
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

stefanok hat geschrieben: Werden in diesem Forum geschlossene Threads als solche gekennzeichnet und wenn ja wie ??
Nein. Einzig die Mods können einen Thread endgültig schließen; das passiert aber eher aus Missbrauch / Verstoß gegen die Forenregeln und ist daher kein reguläres Vorgehen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Na, da habe ich mich auf etwas eingelassen.
Wo liegt denn das Problem? Flask? PDF bauen? Reizüberflutung ;-)?

BTW: welches Prog nutzt du zum Generieren der PDFs? ReportLab?

Gruß, noisefloor
stefanok
User
Beiträge: 6
Registriert: Dienstag 31. Mai 2011, 01:39

Reizüberflutung ist wohl treffend. :shock: :?

Alles angefangen hat mit der Idee spezielle USV über SNMP zu überwachen. Nagios mit check_mk ist da eine schöne Lösung. Die Kommunikation USV <-> Überwachung musste ich selber in Python schreiben, was dann auch ziemlich gut funktioniert hat.
Dann kam die Idee auf, detailliertes Reporting mit allen möglichen Features haben zu wollen. Also habe ich mich in Jasperserver eingearbeitet.

Nun schön, ein Web-Interface soll her. Damit der verwöhnte Benutzer (ist ja auch richtig so) nur eine einzige Oberfläche kennen muss, sollte es sich möglichst ohne aufzufallen in die bestehende Lösung integrieren, gleich aussehen, etc..
(diese ist mit mod_python realisiert)

Nebenbei erwähnt, meine letzten Programme waren in Clipper, über 20 Jahre her. :oops:
Im Vergleich zu Python, Flask und Co. ist da schon ein kleiner Unterschied festzustellen.

Aber, es macht viel Spass, geb ich zu und werde es durchziehen.
Dieses Forum, wo ich einmal mehr über die Qualität und Kompetenz positiv Überrascht bin, ist zusätzlich eine Motivation und Sicherheit den richtigen Weg eingeschlagen zu haben.

Gruss
Stefano
Antworten