Код Python не выполняется - PullRequest
       3

Код Python не выполняется

3 голосов
/ 22 февраля 2012

У меня есть следующий код, который выполняется из командной строки:

import cgi,time,os,json,sys,zipfile,urllib2
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from time import strftime
from poster.encode import multipart_encode, MultipartParam
from poster.streaminghttp import register_openers

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        try:
            if self.path.endswith("/"):
                self.send_response(200)
                self.send_header('Content-type',    'text/html')
                self.end_headers()
                self.wfile.write("<HTML> GET OK.<BR>")
                return  
            return

        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)


    def do_POST(self):
        global rootnode
        ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
        if ctype == 'multipart/form-data':
            query=cgi.parse_multipart(self.rfile, pdict)
        self.send_response(200)
        self.send_header('Content-type',    'text/html')
        self.end_headers()
        file = query.get('file')

        zfile = "C:\Users\VM1\Desktop\data.zip"
        extract_path = "C:\Users\VM1\Desktop\data\\"

        f = open(zfile, "wb")
        f.write(file[0])
        f.close()
        self.wfile.write("POST OK. File received from VM Host")
        print("File received from VM Host.")
        print("Unzipping zip file")
        unzip = zipfile.ZipFile(zfile)
        unzip.extractall(extract_path)
        print "Files extracted to " + extract_path
        scan_path = '"C:\Program Files (x86)\AVG\AVG2012\\avgscana.exe" /repok /report=C:\Users\VM1\Desktop\\avg_scan_results.txt /scan=' + extract_path
        os.system('"%s"' % scan_path)
        self.write_json_report()
        self.upload_json_report()
        return

    def write_json_report(self):
        scan_results = open("avg_scan_results.txt", "r")
        saved = sys.stdout
        f = file('avg_report.json', 'wb')
        sys.stdout = f
        dict2 = {}
        for line in scan_results:
            if ".jpg" in line:
                result = line.split('\\')
                result_split = result[5].split(' ')
                filename = result_split[0]
                raw_status = result_split[3]
                if "OK" in raw_status:
                    status = "Okay"
                    status_code = "0"
                elif "Virus identified" in raw_status:
                    status = raw_status
                    status_code = "1"
                dict2[filename] = {'FileName': filename, 'DateTime': strftime("%Y-%m-%d %H:%M:%S"), 'statusCode': status_code, 'Description': status}
        print json.dumps(dict2)
        sys.stdout = saved
        f.close()
        print ""
        print "JSON report written"
        json_zip = zipfile.ZipFile("avg_report.zip", "w")
        try:
            json_zip.write('avg_report.json')
        finally:
            json_zip.close()
        return

    def upload_json_report(self):
        av_name = "AVG Free 2012"
        av_version = ""
        scan_results = open("avg_scan_results.txt", "r")
        for line in scan_results:
            if "Program version" in line:
                version_split = line.split(', ')
                program_version_full = version_split[0]
                program_version_split = program_version_full.split(' ')
                av_version = program_version_split[2]
        register_openers()
        datagen, headers = multipart_encode({"av_name": av_name, "av_version": av_version, "filename": "avg_report.zip", "content": open("avg_report.zip", "rb")})
        request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
        print "Uploading JSON report"
        print urllib2.urlopen(request).read()
        return

def main():
    try:
        server = HTTPServer(('', 8080), MyHandler)
        print 'Server started..'
        server.serve_forever()
    except KeyboardInterrupt:
        print 'KeyboardInterrupt received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

Остальные функции работали нормально, кроме upload_json_report().Строка Uploading JSON report показывает, но строка после не выполняется.Мой сервер, который прослушивает запрос, ничего не получает.Что-то не так с кодом здесь?Если да, в чем проблема и как ее решить?Заранее большое спасибо.

РЕДАКТИРОВАТЬ: Я создал отдельный клиент со следующими строками из метода:

register_openers()
datagen, headers = multipart_encode({"av_name": av_name, "av_version": av_version, "filename": "avg_report.zip", "content": open("avg_report.zip", "rb")})
request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
print "Uploading JSON report"
print urllib2.urlopen(request).read()

Это сработало.Я не понимаю, почему одни и те же строки кодов не могут работать в функции.

Ответы [ 4 ]

2 голосов
/ 01 марта 2012

BaseHTTPRequestHandler поддерживает однопоточный (и однопроцессный) сервер.Это означает, что каждый запрос должен завершиться до того, как будет выполнен другой запрос.

Функция upload_json_report вызывается из метода do_POST.Пока он работает, ваш сервер не может обрабатывать что-либо еще.Но затем в строке:

    print urllib2.urlopen(request).read()

Вы на самом деле пытаетесь загрузить ZIP-файл на тот же порт, 8080. Таким образом, upload_json_report ожидает do_POST дляFinish, и do_POST ожидает завершения upload_json_report, поэтому, конечно, они никогда не перестанут ждать.

Кстати, это объясняет, почему он работал на вашем сервере (я полагаю, он был многопоточным, хотя вынужно предоставить более подробную информацию), и , почему это работает, когда вы выполняете его с помощью отдельного клиента (он не ждет, пока не завершится).

1 голос
/ 22 февраля 2012

Я бы порекомендовал отладить код. Для этого я бы удалил операторы print, добавил pdb.set_trace непосредственно перед вызовом метода urllib2.urlopen и запустил скрипт. Как только отладчик вступит во владение, я проверю, соответствует ли URL-адрес ожидаемому, попробую выполнить следующую строку и проверим, какое значение возвращает urllib2.urlopen (код ответа, текст и т. Д.). Это должно предоставить вам достаточно информации о том, что происходит, и, надеюсь, даст вам знать, как решить проблему.

0 голосов
/ 01 марта 2012

Я предлагаю добавить "try" "кроме" вокруг строки "urllib2.urlopen", чтобы увидеть, возникло ли какое-либо исключение.

try:
    request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
except Exception, e:
    print e

с напечатанной информацией об исключении, у вас могут быть некоторыеключи.

0 голосов
/ 22 февраля 2012

urllib2.urlopen(...) возвращает объект дескриптора файла, который вы должны прочитать, чтобы распечатать ответ.По сути, чтобы увидеть, какой ответ он получает от сервера, нужно сделать print urllib2.urlopen(request).read()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...