|
@@ -6,13 +6,13 @@ import jinja2
|
|
|
import json
|
|
|
import re
|
|
|
from bs4 import BeautifulSoup
|
|
|
-from xml_prettify import prettify_xml
|
|
|
+from .xml_prettify import prettify_xml
|
|
|
import logging
|
|
|
|
|
|
|
|
|
class c11_api:
|
|
|
webservice = ""
|
|
|
- templates_dir = "tools/cognos11/templates"
|
|
|
+ templates_dir = ""
|
|
|
# templates_dir = "C:/GlobalCube/Tasks/gctools/templates"
|
|
|
export_dir = "C:/GlobalCube/ReportOutput"
|
|
|
log_dir = "C:/GlobalCube/Tasks/gctools/logs"
|
|
@@ -25,11 +25,18 @@ class c11_api:
|
|
|
|
|
|
def __init__(self, webservice="http://localhost:9300/bi/"):
|
|
|
self.webservice = webservice
|
|
|
+
|
|
|
+ self.templates_dir = os.path.dirname(__file__) + '/templates'
|
|
|
self._env = jinja2.Environment(
|
|
|
loader=jinja2.FileSystemLoader(self.templates_dir),
|
|
|
autoescape=jinja2.select_autoescape(['html', 'xml'])
|
|
|
)
|
|
|
- self.template = self._env.get_template('get_report.xml')
|
|
|
+ self.templates = {
|
|
|
+ 'get_report': self._env.get_template('get_report.xml'),
|
|
|
+ 'create_report': self._env.get_template('create_report.xml'),
|
|
|
+ 'update_report': self._env.get_template('update_report.xml'),
|
|
|
+ 'get_package': self._env.get_template('get_package.xml'),
|
|
|
+ }
|
|
|
|
|
|
@staticmethod
|
|
|
def generate_token(message_base64):
|
|
@@ -63,28 +70,29 @@ class c11_api:
|
|
|
|
|
|
self.caf = r.json()['cafContextId']
|
|
|
self.cam = self.generate_token(r.cookies["usersessionid"])
|
|
|
- return r.status_code
|
|
|
+ return self
|
|
|
|
|
|
def get_folders(self):
|
|
|
if len(self.folders) == 0:
|
|
|
+ self.folders.append({'id': '_dot_public_folders', 'name': 'Team Content'})
|
|
|
self.load_folder_list()
|
|
|
return self.folders
|
|
|
|
|
|
def load_folder_list(self, folder_id='_dot_public_folders', prefix='Team Content'):
|
|
|
res = self.session.get(f"{self.webservice}v1/objects/{folder_id}/items", headers=self.headers)
|
|
|
- folder_list = res.json()['data']
|
|
|
+ folder_list = sorted(res.json()['data'], key=lambda x: x['defaultName'])
|
|
|
for f in folder_list:
|
|
|
if f['type'] == 'folder':
|
|
|
folder = {
|
|
|
'id': f['id'],
|
|
|
- 'name': prefix + '/' + f['defaultName'].replace('/', '_')
|
|
|
+ 'name': prefix + '/' + f['defaultName'].replace('/', '-')
|
|
|
}
|
|
|
self.folders.append(folder)
|
|
|
self.load_folder_list(folder['id'], folder['name'])
|
|
|
elif f['type'] == 'report':
|
|
|
report = {
|
|
|
'id': f['id'],
|
|
|
- 'name': f['defaultName'],
|
|
|
+ 'name': f['defaultName'].replace('/', '-'),
|
|
|
'path': prefix
|
|
|
}
|
|
|
self.reports.append(report)
|
|
@@ -140,11 +148,17 @@ class c11_api:
|
|
|
report = self.get_report_specs(report)
|
|
|
return report
|
|
|
|
|
|
- def get_reports_in_folder(self, folder, recursive=False):
|
|
|
+ def get_reports_in_folder(self, folder, recursive=False, specs=False):
|
|
|
self.get_folders()
|
|
|
+
|
|
|
if recursive:
|
|
|
- return [r for r in self.reports if r['path'].startswith(folder)]
|
|
|
- return [r for r in self.reports if r['path'] == folder]
|
|
|
+ res = [r for r in self.reports if r['path'].startswith(folder)]
|
|
|
+ else:
|
|
|
+ res = [r for r in self.reports if r['path'] == folder]
|
|
|
+
|
|
|
+ if specs:
|
|
|
+ return [self.get_report_specs(r) for r in res]
|
|
|
+ return res
|
|
|
|
|
|
def get_report_specs(self, report):
|
|
|
headers = {
|
|
@@ -154,9 +168,11 @@ class c11_api:
|
|
|
'X-UseRsConsumerMode': 'true',
|
|
|
'SOAPAction': 'http://www.ibm.com/xmlns/prod/cognos/reportService/202004/'
|
|
|
}
|
|
|
- soap = self.template.render({"caf": self.caf, "cam": self.cam,
|
|
|
- "report": report, "format": 'XHTML',
|
|
|
- "prompt": 'true', "tracking": "", "params": {}})
|
|
|
+ soap = self.templates['get_report'].render(
|
|
|
+ {"caf": self.caf, "cam": self.cam,
|
|
|
+ "report": report, "format": 'XHTML',
|
|
|
+ "prompt": 'true', "tracking": "", "params": {}}
|
|
|
+ )
|
|
|
|
|
|
r = self.session.post(self.webservice + 'v1/reports', data=soap, headers=headers)
|
|
|
if r.status_code == 500:
|
|
@@ -194,10 +210,10 @@ class c11_api:
|
|
|
report['filename'] = report['filename'].replace('[' + p + ']', '{' + str(i) + '}')
|
|
|
return report
|
|
|
|
|
|
- def export_unstubbed(self, report_id):
|
|
|
+ def request_unstubbed(self, report_id):
|
|
|
report = self.get_report(report_id)
|
|
|
if 'spec' not in report:
|
|
|
- return False
|
|
|
+ return ''
|
|
|
payload = json.dumps({'reportspec_stubbed': report['spec'], 'storeid': report['id']})
|
|
|
|
|
|
headers = {
|
|
@@ -229,31 +245,30 @@ class c11_api:
|
|
|
for cti in bs.find_all('crosstabIntersection'):
|
|
|
if len(list(cti.children)) == 0:
|
|
|
cti.decompose()
|
|
|
- unstubbed_report = str(bs).replace("'", ''')
|
|
|
- unstubbed_report = prettify_xml(unstubbed_report)
|
|
|
-
|
|
|
- filename = self.log_dir + f"/config/{report['path']}/{report['name']}.xml"
|
|
|
- os.makedirs(os.path.dirname(filename), exist_ok=True)
|
|
|
- with open(filename, "w") as f:
|
|
|
- f.write(unstubbed_report)
|
|
|
+ unstubbed_report = str(bs)
|
|
|
+ unstubbed_report = prettify_xml(unstubbed_report).replace("'", '"')
|
|
|
return unstubbed_report
|
|
|
|
|
|
- def get_report_headers(self, report_id):
|
|
|
- return {
|
|
|
+ def get_report_headers(self, report_id=None):
|
|
|
+ res = {
|
|
|
'Content-Type': 'text/xml; charset=UTF-8',
|
|
|
'X-XSRF-TOKEN': self.headers['X-XSRF-TOKEN'],
|
|
|
- 'X-RsCMStoreID': report_id,
|
|
|
'X-UseRsConsumerMode': 'true',
|
|
|
'SOAPAction': 'http://www.ibm.com/xmlns/prod/cognos/reportService/202004/'
|
|
|
}
|
|
|
+ if report_id is not None:
|
|
|
+ res['X-RsCMStoreID'] = report_id
|
|
|
+ return res
|
|
|
|
|
|
def request_file(self, report_id, params, format='PDF'):
|
|
|
report = self.get_report(report_id)
|
|
|
headers = self.get_report_headers(report_id)
|
|
|
|
|
|
- soap = self.template.render({"caf": self.caf, "cam": self.cam,
|
|
|
- "report": report, "format": format,
|
|
|
- "prompt": 'false', "tracking": "", "params": params}).encode("utf-8")
|
|
|
+ soap = self.templates['get_report'].render(
|
|
|
+ {"caf": self.caf, "cam": self.cam,
|
|
|
+ "report": report, "format": format,
|
|
|
+ "prompt": 'false', "tracking": "", "params": params}
|
|
|
+ ).encode("utf-8")
|
|
|
r = self.session.post(self.webservice + 'v1/reports', data=soap, headers=headers)
|
|
|
|
|
|
bs = BeautifulSoup(r.text, 'xml')
|
|
@@ -268,6 +283,67 @@ class c11_api:
|
|
|
logging.debug(error)
|
|
|
return r.status_code, error
|
|
|
|
|
|
+ def create_report(self, folder_id, fullpath):
|
|
|
+ # self.session.get(self.webservice + 'v1/reports/templates?path=%2Fcontent%2Ffolder%5B%40name%3D%27Templates%27%5D/*[@objectClass=%27interactiveReport%27%20or%20@objectClass=%27report%27%20or%20@objectClass=%27reportTemplate%27]&maxResults=100&locale=de')
|
|
|
+ # self.session.get(self.webservice + 'v1/reports/startupconfig?keys=supportedContentLocales,supportedCurrencies,supportedFonts,metadataInformationURI,glossaryURI&locale=de')
|
|
|
+ headers = self.get_report_headers()
|
|
|
+ soap = self.templates['get_package'].render(
|
|
|
+ {"caf": self.caf, "cam": self.cam}
|
|
|
+ ).encode("utf-8")
|
|
|
+ r = self.session.post(self.webservice + 'v1/reports', data=soap, headers=headers)
|
|
|
+ open('package.xml', 'wb').write(r.content)
|
|
|
+
|
|
|
+ search_path = self.request_search_path(folder_id)
|
|
|
+ report_name = os.path.basename(fullpath)
|
|
|
+ unstubbed = open(fullpath, 'rb').read()
|
|
|
+ headers['SOAPAction'] = 'http://www.ibm.com/xmlns/prod/cognos/reportService/202004/.session'
|
|
|
+ headers['Referer'] = 'http://localhost:9300/bi/pat/rsapp.htm'
|
|
|
+ # headers['caf'] = self.caf
|
|
|
+
|
|
|
+ soap = self.templates['create_report'].render(
|
|
|
+ {"caf": self.caf, "cam": self.cam,
|
|
|
+ "search_path": search_path,
|
|
|
+ "report_name": report_name, "unstubbed": unstubbed}
|
|
|
+ ).encode("utf-8")
|
|
|
+ r = self.session.post(self.webservice + 'v1/reports', data=soap, headers=headers)
|
|
|
+ open('request_create.xml', 'wb').write(r.request.body)
|
|
|
+ print(r.status_code)
|
|
|
+ print(r.text)
|
|
|
+
|
|
|
+ def update_report(self, report, fullpath):
|
|
|
+ search_path = self.request_search_path(report['id'])
|
|
|
+ unstubbed = open(fullpath, 'r').read()
|
|
|
+ headers = self.get_report_headers(report['id'])
|
|
|
+ # headers['Referer'] = 'http://localhost:9300/bi/pat/rsapp.htm'
|
|
|
+ headers['caf'] = self.caf
|
|
|
+
|
|
|
+ soap = self.templates['update_report'].render(
|
|
|
+ {"caf": self.caf, "cam": self.cam,
|
|
|
+ "search_path": search_path, "unstubbed": unstubbed}
|
|
|
+ ) # .encode("utf-8")
|
|
|
+ r = self.session.post(self.webservice + 'v1/reports', data=soap, headers=headers)
|
|
|
+ # open('request_update.xml', 'wb').write(r.request.body)
|
|
|
+ print(r.status_code)
|
|
|
+ print(r.text)
|
|
|
+
|
|
|
+ def create_folder(self, parent_id, folder_name):
|
|
|
+ data = json.dumps({"defaultName": folder_name, "type": "folder"})
|
|
|
+ res = self.session.post(
|
|
|
+ f"{self.webservice}v1/objects/{parent_id}/items",
|
|
|
+ headers=self.headers,
|
|
|
+ data=data
|
|
|
+ )
|
|
|
+
|
|
|
+ if res.status_code == 201:
|
|
|
+ loc = res.headers.get('Location')
|
|
|
+ folder_id = loc.split('/')[-1]
|
|
|
+ self.folders.append({'id': folder_id, 'name': folder_name})
|
|
|
+ return folder_id
|
|
|
+
|
|
|
+ def request_search_path(self, id):
|
|
|
+ res = self.session.get(f"{self.webservice}v1/objects/{id}?fields=searchPath", headers=self.headers)
|
|
|
+ return res.json()['data'][0]['searchPath']
|
|
|
+
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
api = c11_api()
|