Новичок
Профиль
Группа: Участник
Сообщений: 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
|