Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не обрабатывается xml-ответ 
:(
    Опции темы
CorvusCorax
Дата 4.3.2011, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 4.3.2011

Репутация: нет
Всего: нет



Имеется прога, работающая в качестве обработчика смс, пересылающая запросы с смс в базу веб-сервера и получающая ответы в виде xml. xml интерфейс на сервере написан на php с использованием flourish. Недавно понадобилось внести изменения в обработчик на сервере, но после того как изменения были внесены часть проги отвечающая за парсинг xml перестала работать. Листинг PHP приколю ниже, а пока о функционале проге:  

1 часть написана на Java (с ней проблем нет), выгребает смски у оператора и пересылает их на localhost:8000, слушаемый 2-й частью писаной на python с django, которая парсит смски, вносит во временную базу данных, составляет из них GET запрос и шлет его на http://server/sms.php (3-я часть, тот самый php-скрипт который модифицируется), тот разобрав запрос проверяет возможноть внесения его в базу и если нет препятствий делает это, а ответы формирует в виде xml. 2 часть проги должна проверить ответ, разобрать его и переслать 1-й части, для отправки ответа оператору и соответственно абоненту. 

Вот листинг PHP-скрипта:
Код

<?php

/*
 * ********************************************
 */

function template($status, $desc="", $nodes="") {

    $response = "<?xml version='1.0' ?>";
    $response .= "<response>";

    $response .= "<result>{$status}</result>";
    $response .= "<description>{$desc}</description>";
    $response .= $nodes;

    $response .= "</response>";

    return $response;
}

/*
 * ********************************************
 */
function pay() {

    global $diler, $db;

    
    $smsid = $_GET['smsid'];
    $pid = $_GET['paymentId'];
    $subscriber = $_GET['subscriber'];
    $prefix = "996" . substr($subscriber, 0, 3);
    $subscriber = substr($subscriber, 3);



    $amount = $_GET['amount'];

    $payment_table = date('Y_m_d');



    # check prefix
    $result = $db->query("SELECT operator_id FROM prefix WHERE prefix = %s", $prefix );

    if ( $result->countReturnedRows() < 1 ) {
        # Invalid prefix
        return template('false', "oshibka prefiksa");
    }

    $operator = $result->fetchScalar();
    
// --  начало измененного блока (раньше тут ничего не было)
    # check operator activity
    
    $act = $db->query("SELECT * FROM operators WHERE id = %s", $operator );
    $opss = $act->fetchRow();        
            if ( $opss['active'] == 0 ) {
           return template('false', "operator {$opss['operator']} otkluichen");
           exit();
        }

// -- конец изменений

    # check limit

    $result = $db->query("SELECT summa FROM pwd_user WHERE id = %i", $diler['id']);
    if ( $result->fetchScalar() < $amount ) {
        return template('false', "limit ischerpan");
        exit();
    }

    # decrease limit
    $db->query( "UPDATE pwd_user SET summa = summa - %f WHERE id = %i LIMIT 1", $amount, $diler['id'] );

// --  начало измененного блока (раньше тут тоже ничего не было)
    # check&decrease group limit


    $admin_id = $db->query("SELECT pwd_admin.id FROM pwd_user, pwd_admin  WHERE pwd_user.id = %i AND pwd_user.user_id=pwd_admin.uid", $diler['id'])->fetchScalar();
    try {
    $result = $db->query("SELECT * FROM pwd_admin_limit WHERE id=%i",$admin_id);
        $glimit = $result->fetchRow();        
            if ( $glimit['summa'] < $amount ) {
           return template('false', "ischerpan gruppovoy limit");
           exit();
        }
        elseif( $glimit['summa'] != 999999) {
                $db->query( "UPDATE pwd_admin_limit SET summa = summa - %i WHERE id = %i LIMIT 1", $amount, $glimit['id'] );
            }
            } catch ( fSQLException $e ) {
           return template('false', 'sistemnaya oshibka');
            } catch ( fNoRowsException $ex ) {
            $glimit = array();
            }
        
// -- конец изменений

    # check for duplicated payments
    try {
        $result = $db->query(
            'SELECT status, id, summa, nomerabonenta, prefix FROM `'.$payment_table.'` WHERE `diler_id`=%i ORDER BY `id` DESC LIMIT 5',
            $diler['id']
        );
    }
    catch ( fSQLException $e ) {
        return template('false', 'sistemnaya oshibka');
    }

    try {
        $lastPayments = $result->fetchAllRows();
    } catch ( fNoRowsException $ex ) {
        $lastPayments = array();
    }

    foreach( $lastPayments as $payment ) {

        if ( $prefix == $payment['prefix'] 
               and $subscriber == $payment['nomerabonenta'] 
               and $amount == $payment['summa'] 
        )
        {
            return template('false', "dublikat");
            exit();
        }
    }



    # insert to payments table

    $query="INSERT INTO {$payment_table} 
        VALUES (
            '', 
            %s, 
            %s, 
            %s, 
            %f, 
            %i, 
            %i, 
            %i, 
            now(),
            '3',
            'wait');";
    try {
        $result = $db->query( $query, 
            $operator, $prefix, $subscriber, $amount, $diler['id'], $diler['group_id'], $diler['user_id']
            );
    }
    catch ( fSQLException $e ) {
        return template('false', 'sistemnaya oshibka');
    }

    $paymentId = $result->getAutoIncrementedValue();


    
    # insert to processor table
    $query = "INSERT INTO `manager` VALUES ( '', %s, %s, %f, %i, %s, 0);";
    $result = $db->query( $query,
        $operator,
        $prefix.$subscriber,
        $amount,
        $paymentId,
        $payment_table);

    # Status ok
    return template('true', "ok", "<smsid>{$smsid}</smsid><pid>{$pid}</pid><paymentId>{$paymentId}</paymentId>");
    
}

/*
 * ********************************************
 */


function cancel() {
    global $diler, $db;


    $paymentId = fRequest::get('paymentId');

    $payment_table = date('Y_m_d');

    # get a payment
    $today = date("Y-m-d").' 00:00:00';

    try {
        $result = $db->query( "SELECT * FROM `{$payment_table}` WHERE `id` = %i AND diler_id = %i AND `data` > %d  LIMIT 1",
            $paymentId, $diler['id'], $today );
    }
    catch ( fSQLException $e ) {
        return template('false', 'sistemnaya oshibka');
    }

    try {
        $payment = $result->fetchRow();
    } catch ( fNoRowsException $ex ) {
        # no such payment
        return template('false', "net takogo plateja", "");
    }



    if ( $payment['operator'] == 2 or $payment['operator'] == 5) {
        # Bitel, O!
        return template('false', "bitel, o! ne otmenyaetsya", "");
    }



    #update a payment table
    $query="UPDATE `{$payment_table}` SET `status` = '2' WHERE `id` =%i and `diler_id` = %i LIMIT 1";
    $result = $db->query( $query, 
        $paymentId, 
        $diler['id']);



    # process 
    if ( $payment['operator'] == 1 
            or $payment['operator'] == 3
            or $payment['operator'] == 4 )
    {
        $query = "INSERT INTO `manager` VALUES ('', %s, %s, %f, %i, %s, 1)";

        $db->query( $query,
            $payment['operator'],
            $payment['prefix'].$payment['nomerabonenta'],
            $payment['summa'],
            $payment['id'],
            $payment_table 
        );

    }

    # ok
    return template('true', "", "");

}

/*
 * ********************************************
 */


function check() {

    global $diler, $db;

    $paymentId = $_GET['paymentId'];
    $payment_table = date('Y_m_d');

    #get payment
    try {
        $result = $db->query("SELECT * FROM {$payment_table} WHERE id = %i AND diler_id = %i", $paymentId, $diler['id']);
        $payment = $result->fetchRow();

    } catch ( fSQLException $e ) {
        return template('false', 'sistemnaya oshibka');

    } catch ( fNoRowsException $ex ) {
        # no such payment
        return template('false', "net takogo plateja", "");
    }

    #payment data
    return template('true', "","<payment><id>{$payment['id']}</id><status>{$payment['status']}</status><desc>{$payment['comment']}</desc></payment>");

}

/*
 * ********************************************
 */


function report() {
    global $diler, $db;
    $payment_table = date('Y_m_d');

    $dateSStr =   fRequest::get('date_s');
    $datePoStr =   fRequest::get('date_po');

    #check date
    $dateSChunks = explode( ".", $dateSStr );
    $dateS = mktime( 0,0,0, $dateSChunks[1], $dateSChunks[0], $dateSChunks[2] );

    if ( $datePoStr ) {
        $datePoChunks = explode( ".", $datePoStr );
        $datePo = mktime( 0,0,0, $datePoChunks[1], $datePoChunks[0], $datePoChunks[2] );
    }

    if ( $dateS ) {

        if ( isset($datePo) ) {

            if ( $dateS < $datePo ) {
                # mnogo dney

                # get operators list
                $query = "SELECT id, operator FROM `operators`";
                $result = $db->query( $query );
                foreach( $result as $row) {
                    $operators[ $row['id'] ] = $row['operator'];
                    $ret[ $row['operator'] ] = 0;
                }

                $amounts = array();
                for( ; $dateS <= $datePo; $dateS += 60*60*24) {
                    $amountList = getAmount( date( 'Y_m_d' , $dateS ) );
                    foreach( $operators as $operator) {
                        $ret[ $operator ] += $amountList[ $operator ];
                    }
                }
                $summa = serializeArray( $ret);
                return template( 'true', "otchet za {$dateSStr}-{$datePoStr} {$summa} som");


            } else {
                return template('false', "nepravil'nyie daty" );
            }

        } else {
            #odin den'
            $summa = serializeArray( getAmount( date ( 'Y_m_d', $dateS ) ) );

            return template( 'true', "otchet za {$dateSStr} {$summa}");

        }

    } else {
        return template('false', "nepravil'naya data" );
    }

}

/*
 * ********************************************
 */

function getAmount($table_name) {
    global $db, $diler;

    $query = "SELECT id, operator FROM `operators`";
    $result = $db->query( $query );
    foreach( $result as $row) {
        $operators[ $row['id'] ] = $row['operator'];
        $ret[ $row['operator'] ] = 0;
    }

    $query = "SELECT SUM(summa) summa, operator FROM {$table_name} WHERE diler_id = %i AND status = %i GROUP BY operator";

    try {
        $result = $db->query( $query, $diler['id'], 0 );
        foreach($result as $row) {
            $ret[ $operators[ $row[ 'operator' ] ] ] += $row['summa'];
        }
    } catch ( fSQLException $e ) {
        return 0;

    } 
    return $ret;
}

function serializeArray($arr) {
    $ret = "";
    if (is_array($arr)) {
        foreach( $arr as $k=>$v ) {
            $ret .= strtolower($k).":{$v}; ";   
        }
    }
    return $ret;
}
?>



Добавлено @ 17:26
Вот файлы второй части в которых я нашел хоть какой-то намек на парсинг ответов:
yaros_client.py
Код


from smsprocessor.payments.webclient import WebClient
import smsprocessor.settings
from smsprocessor.logger import logger
import xml.dom.minidom
import re

class Yaros_Client:

    def check_payment(self,payment_id, src, pin):
        webclient = WebClient()

        url = "%s?username=%s&password=%s&action=check&paymentId=%s" % (
                    smsprocessor.settings.SMS_URL,
                    src,
                    pin,
                    payment_id
                )

        logger.info( "Check URL: %s" % url )

        responseText = webclient.get( url )

        logger.info( "Check response: %s" % responseText )

        dom = xml.dom.minidom.parseString( responseText )

        try:
            result = dom.getElementsByTagName("result")[0].childNodes[0].data
        except:
            pass

        try:
            description = dom.getElementsByTagName("description")[0].childNodes[0].data
        except:
            pass

        status = None
        try:
            status = dom.getElementsByTagName("status")[0].childNodes[0].data
        except:
            pass

        comment = None
        try:
            comment = dom.getElementsByTagName("desc")[0].childNodes[0].data
        except:
            pass

        if status == '0' and ( comment == "ok" or re.match( r".+:\d+",  comment ) ):
            statusStr = "uspeshnyi"

        elif status == "0":
            statusStr = "uspeshnyi"

        elif status == "1":
            statusStr = "ne proplachen"

        elif status == "3":
            statusStr = "v ojidanii"

        else:
            statusStr = "ne proplachen"



        if result == "true":
            return statusStr
        else:
            return "oshibka: %s" % description



tasks.py
Код

import singleton
import time
import xml.dom.minidom
from threading import Thread
from smsprocessor.payments.webclient import WebClient
from smsprocessor.payments.models import Payment
from smsprocessor.payments import statusCodes
from smsprocessor.payments.webclient import WebClient
from smsprocessor.payments.yaros_client import Yaros_Client

from smsprocessor import settings
from smsprocessor.logger import logger

import outgoing_queue


class Response:

    def __init__(self):
        self.result = None
        self.description = None
        self.smsid = None

    def __str__(self):
        return "[Response result=%s description=%s smsid=%s]" % ( self.result, self.description, self.smsid )


"""
*
* 
*
"""

class PaymentTask(Thread):

    def __init__(self, payment):
        self.response = None
        self.payment = payment
        Thread.__init__(self)

    def run(self):
        webclient = WebClient()

        url = "%s?username=%s&password=%s&action=pay&smsid=%s&paymentId=%s&subscriber=%s&amount=%s" % (
                    settings.SMS_URL,
                    self.payment.sms.src,
                    self.payment.sms.pin,
                    self.payment.sms.id,
                    self.payment.id,
                    self.payment.subscriber,
                    self.payment.amount
                )


        logger.info( "Payment URL: %s" % url )
        responseText = webclient.get( url )

        logger.info( "Payment response: %s" % responseText )

        self.response = self.parseResponse( responseText )
        self.response.pin = self.payment.sms.pin


    def parseResponse(self, responseText):
        response = Response()
        dom = xml.dom.minidom.parseString( responseText )

        try:
            response.result = dom.getElementsByTagName("result")[0].childNodes[0].data
        except:
            pass

        try:
            response.description = dom.getElementsByTagName("description")[0].childNodes[0].data
        except:
            pass

        try:
            response.smsid = dom.getElementsByTagName("smsid")[0].childNodes[0].data
        except:
            pass

        try:
            response.id = dom.getElementsByTagName("pid")[0].childNodes[0].data
        except:
            pass

        try:
            response.remote_id = dom.getElementsByTagName("paymentId")[0].childNodes[0].data
        except:
            pass

        return response




class Task:

    def __init__ (self, sms):
        self.sms = sms 




"""
*
* Main Thread
*
"""
class CancelTask(Task):

    def run(self):
        webclient = WebClient()

        url = "%s?username=%s&password=%s&action=cancel&paymentId=%s" % (
                    settings.SMS_URL,
                    self.sms.src,
                    self.sms.pin,
                    self.sms.args[0]
                )

        logger.info( "Cancel URL: %s" % url )

        responseText = webclient.get( url )

        logger.info( "Cancel response: %s" % responseText )

        dom = xml.dom.minidom.parseString( responseText )

        try:
            result = dom.getElementsByTagName("result")[0].childNodes[0].data
        except:
            pass

        try:
            description = dom.getElementsByTagName("description")[0].childNodes[0].data
        except:
            pass

        if result == "true":
            # send message
            outgoing_queue.send(self.sms.src, "platej %s otmenen" % self.sms.args[0] )
        else:
            # send message desciption
            outgoing_queue.send(self.sms.src, "oshibka otmeny plateja %s: %s" % (self.sms.args[0], description) )





"""
*
* 
*
"""
class ReportTask(Task):

    def run(self):
        webclient = WebClient()

        url = "%s?username=%s&password=%s&action=report&date_s=%s" % (
                    settings.SMS_URL,
                    self.sms.src,
                    self.sms.pin,
                    self.sms.args[0]
                )
        if self.sms.args.__len__() > 1:
            url += "&date_po=%s" % self.sms.args[1]


        logger.info( "Report URL: %s" % url )

        responseText = webclient.get( url )

        logger.info( "Report response: %s" % responseText )

        dom = xml.dom.minidom.parseString( responseText )

        try:
            result = dom.getElementsByTagName("result")[0].childNodes[0].data
        except:
            pass
        if result == "false":
            outgoing_queue.send(self.sms.src, "oshibka pri generacii otcheta")

        try:
            description = dom.getElementsByTagName("description")[0].childNodes[0].data
        except:
            pass

        # send message from description
        outgoing_queue.send(self.sms.src, description )




"""
*
* ***
*
"""
class CheckTask(Task):

    def run(self):
        webclient = WebClient()

        url = "%s?username=%s&password=%s&action=check&paymentId=%s" % (
                    settings.SMS_URL,
                    self.sms.src,
                    self.sms.pin,
                    self.sms.args[0]
                )

        logger.info( "Check URL: %s" % url )

        responseText = webclient.get( url )

        logger.info( "Check response: %s" % responseText )

        dom = xml.dom.minidom.parseString( responseText )

        try:
            result = dom.getElementsByTagName("result")[0].childNodes[0].data
        except:
            pass

        try:
            description = dom.getElementsByTagName("description")[0].childNodes[0].data
        except:
            pass

        status = None
        try:
            status = dom.getElementsByTagName("status")[0].childNodes[0].data
        except:
            pass

        comment = None
        try:
            comment = dom.getElementsByTagName("desc")[0].childNodes[0].data
        except:
            pass

        if status == '0' and comment == "ok":
            statusStr = "uspeshnyi"

        elif status == "1":
            statusStr = "ne proplachen"

        elif status == "3":
            statusStr = "v ojidanii"

        else:
            statusStr = "ne proplachen"



        if result == "true":
            # send message
            outgoing_queue.send(self.sms.src, "status plateja %s: %s" % ( self.sms.args[0], statusStr) )
        else:
            # send message desciption
            outgoing_queue.send(self.sms.src, "oshibka statusa: %s" % ( description) )
        pass




"""
*
* PayTask
*
"""
class PayTask(Task):

    def run(self):
        sms = self.sms
        paymentTasks = []
        i = 0
        while i < sms.args.__len__():
            payment = Payment()
            payment.src = sms.src
            payment.pin = sms.pin
            payment.subscriber = sms.args[i]
            payment.amount = sms.args[i+1]
            payment.sms = sms
            payment.status = statusCodes.NEW

            payment.save()

            paymentTask = PaymentTask(payment)
            paymentTasks.append( paymentTask )
            paymentTask.start()

            i += 2

        for paymentTask in paymentTasks:

            paymentTask.join()

            response = paymentTask.response

            if response.result == "true":
                payment = Payment.objects.get( id = response.id )

                payment.status = statusCodes.SUCCESS
                payment.remote_id = response.remote_id
                time.sleep(10)
                status = Yaros_Client().check_payment(payment.remote_id, payment.src, response.pin)
                outgoing_queue.send(self.sms.src, "platej na %s (id: %s) %s" % ( payment.subscriber, payment.remote_id, status ) )


            elif response.result == "false":

                payment.status = statusCodes.ERROR
                outgoing_queue.send(self.sms.src, "oshibka. status: %s" % ( response.description) )

            else:
                payment.status = statusCodes.SUSPENDED
                outgoing_queue.send( self.sms.src, "systemnaya oshibka" )

            payment.save()







"""
*
* 
*
"""
class TaskFactory(singleton.Singleton):

    def getTask(self, type, sms):
        if type == "pay":
            return PayTask(sms)

        if type == "cancel":
            return CancelTask(sms)

        if type == "check":
            return CheckTask(sms)

        if type == "report":
            return ReportTask(sms)



Вторую часть сообщения пришлось прикрепить, поскольку двиг форума считает что я слишком много написал)))

Это сообщение отредактировал(а) CorvusCorax - 4.3.2011, 17:34

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  log 4,88 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Веб-разработка и фреймворки | Следующая тема »


 




[ Время генерации скрипта: 0.0477 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.