Created
February 22, 2016 16:01
-
-
Save fallenflint/1ef836798af5f1938ecf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
from xml.etree import ElementTree as ET | |
import logging | |
from django.conf import settings | |
from .exceptions import TransactionError | |
if settings.PREMIERE_LOG_TO_DB: | |
from ..models import RequestLog | |
log = logging.getLogger(__name__) | |
class Premiere(object): | |
ALLOWED_METHODS = ( | |
'DiscountMigration', 'GetAssociations', 'GetCardBalance', | |
'GetCardTransactions', 'GetDiscountMigrations', 'GetHallGeometries', | |
'GetHallPlan', 'GetHalls', 'GetMovies', 'GetReservationTypes', | |
'GetReservations', 'GetSales', 'GetSessionPrices', 'GetSessions', | |
'Reservation', 'ReservationClear', 'ReturnOpenDateTickets', | |
'SaleApproved', 'SaleCancel', 'SaleOpenDateTickets', 'SalePayReturn', | |
'SaleReservation', 'GetAllMovieProperties', 'GetFirstMovieSession', | |
'SheduleSessions', 'Query_CardSystem', 'Login', | |
) | |
def __init__(self, url=None, sid=None): | |
if url is None: | |
url = settings.PREMIERE_URL | |
if sid is None: | |
sid = settings.PREMIERE_SID | |
self.url = url | |
self.sid = sid | |
log.debug('Created instance to access %s with sid %s' % (url, sid)) | |
def _get(self, **kwargs): | |
log.debug('Calling method %s' % kwargs['QueryCode']) | |
default_kwargs = { | |
'ServiceID': self.sid, | |
'Encoding': 'Windows-1251', | |
'Version': 3, | |
} | |
default_kwargs.update(kwargs) | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
host, port = self.url.split(':') | |
port = int(port) | |
sock.connect((host, port)) | |
msg_string = '' | |
for key, value in default_kwargs.iteritems(): | |
msg_string += '&{key}={val}'.format(key=key, val=value) | |
length = '{:0>10}'.format(len(msg_string)-1) | |
msg_string = length + msg_string | |
sock.send(msg_string) | |
resp_len = sock.recv(10) | |
response = '' | |
while len(response) < int(resp_len): | |
to_read = min(int(resp_len), 1024) | |
response += sock.recv(to_read) | |
sock.shutdown(socket.SHUT_RDWR) | |
sock.close() | |
if settings.PREMIERE_LOG_TO_DB: | |
self.log_event(default_kwargs.get('QueryCode'), query_string=msg_string) | |
log.debug('Param string: "%s"' % msg_string) | |
self._resp = response | |
log.debug('Got response: "%s"' % response.decode('windows-1251').encode('utf-8')) | |
return self.parse_response(response) | |
def __getattr__(self, attname): | |
if attname not in self.ALLOWED_METHODS: # TODO: fix the list of allowed methods | |
raise AttributeError('Method is not allowed') | |
return self._get_by_method(attname) | |
def _get_by_method(self, attname): | |
def func(**kwargs): | |
kwargs['QueryCode'] = attname | |
return self._get(**kwargs) | |
return func | |
def parse_response(self, value): | |
value = value[1:] #bug in Premiere response - it's not a valid XML | |
if hasattr(self, 'proxy'): | |
start, end = value.find('<Data><![CDATA[') + 15, value.rfind(']]></Data>') | |
value = value[start:end] | |
# self._resp = value | |
root = ET.fromstring(value) | |
if hasattr(self, 'proxy'): | |
return root | |
status = root.find('Result').text | |
error_code = root.find('Error').text | |
error_message = root.find('Remark').text | |
data = root.find('Data') | |
if status != 'Ok': | |
log.debug('Premiere response returned error!') | |
raise TransactionError('Error ocured: (%s) %s' % (error_code, error_message.encode('utf-8'))) | |
return data | |
def log_event(self, method_name, query_string): | |
RequestLog.objects.create(method=method_name, query_string=query_string) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment