Files
xmlrpcserver/main.py
2023-04-02 15:31:43 +03:00

271 lines
8.6 KiB
Python

import asyncio
import threading
import time
from queue import Queue
import datetime
import json
from uuid import uuid4, UUID
from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.client import ServerProxy
import logging
import os
import os.path
import requests
from reqs.graphql import get_catalog, get_object
from pygost import gost34112012256
import xml.etree.ElementTree as ET
from reqs.request_xml_service import RequestXmlService
import zipfile
PASSWORD = 'gost_2012$a742ec53198ec2a5027086fba8814a89982a57112d1a72d02260161108f39b50'
tasks = Queue()
connected = False
def run_tasks():
while True:
task = tasks.get()
task()
def replication_task():
while not connected:
time.sleep(1)
date = datetime.datetime.now()
rxmls = RequestXmlService()
res_id = uuid4().hex
res = rxmls.get_request_document(res_id, None)
res.set('replication_package', '1')
rxmls.set_result(res, 0, '')
response_params = {
'from': 'tcp://bnd127',
'to': 'tcp://kptsp_vb',
'ts_added': date.timestamp(),
'user_id': '0',
'query_type': 1114,
'query_data': ET.tostring(res, encoding='unicode', xml_declaration=True)
}
filename = '51a8a2c81f774af7bba61b475b4b51b5'
filepath = '/tmp/' + filename
response_files = [{'name': filename, 'url': filepath, 'size': os.path.getsize(filepath)}]
logging.info('Send replication package')
proxy = ServerProxy('http://127.0.0.1:7000/xmlrpc')
proxy.send(response_params, response_files, 'http://10.10.8.27:9000/')
# Expose a function
def list_contents(dir_name):
logging.info('list_contents(%s)', dir_name)
return os.listdir(dir_name)
def aud_add(message):
global connected
if not isinstance(message, list):
logging.warning(message)
return 'OK'
for item in message:
logging.warning(item)
if item.get('level', -1) == 0 and item.get('type', -1) == 4002:
connected = True
return 'OK'
def auth_response(challenge, server_id, is_server):
# logging.debug(f'Challenge: {challenge}, Server: {server_id}, IsServer: {is_server}')
msg = '%s%s%s' % (challenge, server_id, PASSWORD)
response = gost34112012256.new(msg.encode('utf-8')[::-1]).digest()[::-1].hex()
return {'error': False, 'response': response}
def auth_challenge():
# logging.debug('get challenge')
return uuid4().hex
def restore_uuid(oid):
uuid = UUID(oid)
return str(uuid)
def load_catalog(params, files, url):
logging.debug('load_catalog')
date = datetime.datetime.now()
rxmls = RequestXmlService()
req = ET.fromstring(params['query_data'])
req_id = rxmls.get_request_uuid(req)
res_id = uuid4().hex
res = rxmls.get_request_document(res_id, req_id)
rxmls.set_result(res, 0, '')
response_params = {
'from': params['to'],
'to': params['from'],
'ts_added': date.timestamp(),
'user_id': '1',
'user_id_to': params['user_id'],
'query_type': 1004,
'query_data': ET.tostring(res, encoding='unicode', xml_declaration=True)
}
catalog = get_catalog()
logging.debug('Catalog_loaded')
filename = uuid4().hex
filepath = '/tmp/' + filename
zipf = zipfile.ZipFile(filepath, "w")
zipf.writestr('WF.CLL', catalog)
zipf.close()
response_files = [{'name': filename, 'url': filepath, 'size': os.path.getsize(filepath)}]
proxy = ServerProxy(url)
proxy.send(response_params, response_files, 'http://10.10.8.27:9000/')
def get_objects(params, files, url):
date = datetime.datetime.now()
rxmls = RequestXmlService()
req = ET.fromstring(params['query_data'])
req_id = rxmls.get_request_uuid(req)
res_id = uuid4().hex
res = rxmls.get_request_document(res_id, req_id)
rxmls.set_result(res, 0, '')
objs = req.find('objects')
uids = [restore_uuid(x.get('object_id')) for x in objs.findall('object')]
rxmls.set_result(res, 0, '')
response_params = {
'from': params['to'],
'to': params['from'],
'ts_added': date.timestamp(),
'user_id': '1',
'user_id_to': params['user_id'],
'query_type': 1001,
'query_data': ET.tostring(res, encoding='unicode', xml_declaration=True)
}
filename = uuid4().hex
filepath = '/tmp/' + filename
zipf = zipfile.ZipFile(filepath, "w")
main_filename = None
for uid in uids:
obj = json.loads(get_object(uid))
for file in obj['properties'].get('c1000', []):
if not main_filename:
main_filename = file['fileName']
res = requests.get(f'https://gql.ivazh.ru/item/{file["key"]}')
zipf.writestr(f'{main_filename}/{file["fileName"]}', res.content)
zipf.close()
response_files = [{'name': filename, 'url': filepath, 'size': os.path.getsize(filepath)}]
proxy = ServerProxy(url)
proxy.send(response_params, response_files, 'http://10.10.8.27:9000/')
def get_metadata(params, files, url):
date = datetime.datetime.now()
rxmls = RequestXmlService()
req = ET.fromstring(params['query_data'])
req_id = rxmls.get_request_uuid(req)
res_id = uuid4().hex
res = rxmls.get_request_document(res_id, req_id)
rxmls.set_result(res, 0, '')
objs = req.find('getMetadataByIds')
uids = [restore_uuid(x.get('id')) for x in objs.findall('chart')]
rxmls.set_result(res, 0, '')
response_params = {
'from': params['to'],
'to': params['from'],
'ts_added': date.timestamp(),
'user_id': '1',
'user_id_to': params['user_id'],
'query_type': 1024,
'query_data': ET.tostring(res, encoding='unicode', xml_declaration=True)
}
filename = uuid4().hex
filepath = '/tmp/' + filename
zipf = zipfile.ZipFile(filepath, "w")
content = ET.Element('getMetadataResponse')
for uid in uids:
obj = json.loads(get_object(uid))
date = datetime.datetime.fromisoformat(obj['date_updated'])
chart = ET.SubElement(content, 'chart', {
'id': UUID(obj['uid']).hex,
'updated': str(date.timestamp()),
})
for key in obj['properties']:
if not key.startswith('c'):
continue
mdel = ET.SubElement(chart, 'mdItem', {
'code': key.replace('_', '.'),
'name': key,
'value': str(obj['properties'].get(key, '')),
'isBase': 'false',
'groupId': '',
'groupName': '',
})
zipf.writestr(f'metadata.xml', ET.tostring(content, encoding='unicode', xml_declaration=True))
zipf.close()
response_files = [{'name': filename, 'url': filepath, 'size': os.path.getsize(filepath)}]
proxy = ServerProxy(url)
proxy.send(response_params, response_files, 'http://10.10.8.27:9000/')
def run_task(query_type, params, files, url):
if query_type == 4:
tasks.put(lambda: load_catalog(params, files, url))
if query_type == 1:
tasks.put(lambda: get_objects(params, files, url))
if query_type == 24:
tasks.put(lambda: get_metadata(params, files, url))
def accept(params, files, url):
print(params, files, url)
print('Accept')
run_task(params['query_type'], params, files, url)
return True
def onSent(params, files, callback_url):
logging.debug('onSent')
def onDelivered(params, files, callback_url):
logging.debug('onDelivered')
def main():
logging.debug('Use Control-C to exit')
logging.basicConfig(level=logging.DEBUG)
server = SimpleXMLRPCServer(('0.0.0.0', 9000), logRequests=False, allow_none=True)
server.register_function(list_contents)
server.register_function(aud_add)
server.register_function(auth_response)
server.register_function(auth_challenge)
server.register_function(accept)
server.register_function(onSent)
server.register_function(onDelivered)
thread = threading.Thread(target=run_tasks)
thread.start()
replication_thread = threading.Thread(target=replication_task)
replication_thread.start()
try:
server.serve_forever()
except KeyboardInterrupt:
logging.debug('Exiting')
def test():
#params = {"from": "tcp://kptsp_vb", "query_data": "<?xml version=\"1.0\" encoding=\"utf-8\"?><request><header parcel_id=\"990715ba919544a98f22cc7d3b0d9e8d\"/><getMetadataByIds><chart id=\"fc44343bd1654ee7b03ac1731567bbfd\"/></getMetadataByIds></request>", "query_type": 24, "to": "tcp://bnd127", "user_id": "3302", "ts_added": 1679825320.653038}
#files = []
#url = 'http://127.0.0.1:7000/xmlrpc'
# accept(params, files, url)
#get_metadata(params, files, url)
get_catalog()
if __name__ == '__main__':
main()
# test()