BaseHTTPServer Datei erstellen mit GET Methode

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Brawn
User
Beiträge: 11
Registriert: Dienstag 21. Januar 2014, 22:38

Hallo Forum,

Ich habe eine Aufgabe, und zwar Werte von einem Gerät über http empfangen und in eine Datei Strukturiert schreiben.
Mit der POST Methode funktioniert es ja (da ich das ganze File übertrage *Test und erste Schritte*), aber leider macht es dieses Gerät über die GET Methode.
Und da hänge ich jetzt ein wenig.

Also zum Client (zu Testzwecken)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib2
import urlparse
import os
import sys
import csv
import time

#sysin = sys.argv[1]

def make_url(server, port, path, scheme='http'):
    netloc = '{}:{}'.format(server, port)
    url = urlparse.urlunsplit((scheme, netloc, path, '', ''))
    return url

##dt = time.strftime("%Y-%m-%d")
#
# Main
#
###
server = 'localhost'
port = 9001


# Transfer over GET
transfer = "/&d0=027124&ci=0&Typ=1&Beginn=220856&z220856=155301130514,0.121,25.7,0.250,5.62,24.97,0.121,0,0,49&z220857=155307130514,0.122,25.7,0.250,5.63,24.97,0.122,0,0,4F&z220858=103217280514,-0.043,23.7,0.049,5.35,25.34,-0.043,0,0,4C&z220859=103237280514,-0.042,23.7,0.049,5.35,25.34,-0.042,0,0,4F&z220860=103514280514,-0.042,23.9,0.049,5.35,25.41,-0.042,0,0,4F&z220861=103629280514,-0.042,23.9,0.049,5.75,25.41,-0.042,0,0,47&z220862=104500280514,-0.042,24.0,0.049,5.53,25.66,-0.042,0,0,44&z220863=110000280514,-0.023,24.3,0.049,5.85,25.66,-0.023,0,21,7E&z220864=111500280514,-0.025,24.4,0.049,5.85,25.34,-0.025,0,21,7D&z220865=113000280514,-0.026,24.4,0.049,5.86,25.13,-0.026,0,19,76&z220866=114500280514,-0.027,24.4,0.049,5.86,24.84,-0.027,0,19,78&z220867=120000280514,-0.027,24.5,0.048,5.87,24.81,-0.027,0,20,75&z220868=121500280514,-0.028,24.5,0.048,5.86,24.69,-0.028,0,20,79&z220869=123000280514,-0.029,24.0,0.048,5.87,24.28,-0.029,0,18,75&z220870=124500280514,-0.030,23.6,0.049,5.87,23.81,-0.030,0,18,7B&Ende=220870"
url = make_url(server, port, transfer)
##contents = urllib2.urlopen(url).read()
##print contents

# send TXT File
##filename = sysin
##contents = open(sysin).read()
##url = make_url(server, port, filename)
##f = urllib2.urlopen(url, data=contents)

# Send quit signal
url = make_url(server, port, '/quit')
urllib2.urlopen(url).read()
Ich weiss es sind mehr Bibliotheken importiert als in verwendung, aber es ich auch nur zu Testzwecken.

Unter "Transfer over GET" sieht man den transfer String was das Gerät übertragt.

Den Server habe ich bis jetzt so geschrieben:
Dabei habe ich auch schon mit einem Dictionary probiert.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from urlparse import urlparse, parse_qs
import os
import sys
import time

sdate = time.strftime("%Y-%m-%d")
stime = time.strftime("%H-%M-%S")


class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global running
        if self.path.startswith('/'):
##        if self.path == '/':
            self.wtemp_files()
        elif self.path.startswith('/quit'):
            self.send_response(200)
            running = False
        else:
            self.send_file(self.path[1:])

    def wtemp_files(self):
        query_components = parse_qs(urlparse(self.path).query)
        with open("testname", 'w') as f:
            f.write(query_components())

##        query_components = dict(qc.split("=") for qc in query.split("&"))
##        # order type to Special Charakter
##        d0 = query_components["d0"]
##        typereq = query_components["ci"]
##        typ = query_components["Typ"]
##        with open('testname', 'w') as f:
##            f.write(query())

        self.send_response(200)

    def do_POST(self):
        filename = self.path[1:] 
        newfname = (sdate+"_"+stime+"_"+filename)
        filesize = int(self.headers['Content-Length'])
        contents = self.rfile.read(filesize)

        with open(filename, 'w') as f:
            f.write(contents.decode())

        self.send_response(200)

##        if os.path.isfile(filename):
##            ###print("rename "+filename+" "+newfname)
##            os.system("rename "+filename+" "+newfname)
##        else:
##            print("fehler bei "+newfname)


#
# Main
#
running = True
server = HTTPServer(('localhost', 9001), MyHandler)
print 'Server started on host:{}, port:{}'.format(*server.server_address)
while running:
    server.handle_request()
Wie kann ich jetzt am Server den Empfangenen String in eine Datei schreiben und bei jedem "&" in eine neue Zeile gehen?

Ich weiss es sieht viel aus, aber nur so kann man das Ratespiel fast vermeiden. :mrgreen:

Danke schonmal im Vorraus für eure Hilfe. 8)
Shortfinga
User
Beiträge: 2
Registriert: Samstag 24. Mai 2014, 12:43

Brawn hat geschrieben:Hallo Forum,

Code: Alles auswählen


url = make_url(server, port, transfer)
##contents = urllib2.urlopen(url).read()
##print contents

# send TXT File
##filename = sysin
##contents = open(sysin).read()
##url = make_url(server, port, filename)
##f = urllib2.urlopen(url, data=contents)

# Send quit signal
url = make_url(server, port, '/quit')
urllib2.urlopen(url).read()
Kann es sein, dass da ein urllib-Aufruf fehlt? Du baust die URL und rufst sie aber nicht ab.
Brawn hat geschrieben:

Code: Alles auswählen

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global running
        if self.path.startswith('/'):
##        if self.path == '/':
            self.wtemp_files()
        elif self.path.startswith('/quit'):
            self.send_response(200)
            running = False
        else:
            self.send_file(self.path[1:])
Das sieht nach totem Code aus, entweder zuerst das quit abfangen oder die erste if-Bedingung präzisieren...
Brawn hat geschrieben: Wie kann ich jetzt am Server den Empfangenen String in eine Datei schreiben und bei jedem "&" in eine neue Zeile gehen?

Ich weiss es sieht viel aus, aber nur so kann man das Ratespiel fast vermeiden. :mrgreen:

Danke schonmal im Vorraus für eure Hilfe. 8)
Wenn du die Url, bzw. den query nicht decodierst kannst du nen replace machen. Andernfalls beginnt bei & eigentlich ein neuer parameter, über die kannst du evtl iterieren...

LG
Shorti
Brawn
User
Beiträge: 11
Registriert: Dienstag 21. Januar 2014, 22:38

Hy, vielen dank für die Hilfe.

Hab es komplett übersehen die "url" beim client zusammenzusetzen und übergeben.
Jetzt funktioniert auch die Übertragung und habe gleich die "&" mit "\n" ersetzt.
Somit wird jetzt genau die Datei erzeugt wie ich es haben wollte.

Jetzt habe ich nur noch ein kleines Problem.
Und zwar erstellt mir der server immer nur eine Datei.

Also wenn ich den Server Starte und laufen lasse, erstellt der mir nur eine Datei und danach keine mehr.
Obwohl laut der Ausgabe auch noch die zweite Anfrage rein kommt.
Nur erstellt der mir keine Datei mehr.?

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import os
import sys
import time

sdate = time.strftime("%Y-%m-%d")
stime = time.strftime("%H-%M-%S")


class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global running
        if self.path == '/':
            self.wtemp_files()
        elif self.path.startswith('/&d'):
            self.wtemp_files()
        elif self.path.startswith('/quit'):
            self.send_response(200)
            running = False
        else:
            self.send_file(self.path[1:])

    def wtemp_files(self):
        content = self.path[2:]
        filename = (sdate+"-"+stime+"_"+content[3:9])
        repcontent = content.replace('&', '\n')
        with open(filename, 'w') as f:
            f.write(repcontent.decode())

        self.send_response(200)

    def send_file(self, filename):
        # Check to see if file exists and is a file, not directory
        if os.path.isfile(filename):
            self.send_response(200)
            self.send_header('Content-Type', 'text/plain')
            self.end_headers()

            # Read and send the contents of the file
            with open(filename) as f:
                contents = f.read()
            self.wfile.write(contents)
        else:
            self.send_response(404)
            self.send_header('Content-Type', 'text/plain')
            self.end_headers()
            self.wfile.write('Dude! File not found')

#
# Main
#
running = True
server = HTTPServer(('127.0.0.1', 9001), MyHandler)
print 'Server started on host:{}, port:{}'.format(*server.server_address)
while running:
    server.handle_request()

Mir ist klar, das der Code noch verbesserungswürdig ist.

Aber zuerst möchte ich wissen wo ich da einen Fehler gemacht habe. :K

Danke :mrgreen:
Brawn
User
Beiträge: 11
Registriert: Dienstag 21. Januar 2014, 22:38

OK bin soeben draufgekommen, dass er keinen neuen Dateinamen erstellt.

Obwohl ich am Dateinamen noch Datum und Uhrzeit angefügt habe.

Laut der Print Ausgabe, erstellt er immer die gleiche Datei (sogar Datum und Zeit ist gleich).

Habe ich da irgendwo ein Ausgang vergessen ?
Da es ja sonst umöglich ist immer die gleiche Zeit zu bekommen.

LG :D
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Brawn:
`sdate` und `stime` hast Du global, was dazu führt, dass die nur einmal zum Skriptstart gesetzt werden.
Brawn
User
Beiträge: 11
Registriert: Dienstag 21. Januar 2014, 22:38

Wow Cool, danke.

Das wars... :D

PS.: Wie kann man den Thread als "Gelöst" markieren ?!
Antworten