mdl_convert.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. import json
  2. import re
  3. def get_field(field, block, num=1):
  4. if num == 2:
  5. res = re.search(field + r' (\d+) "([^"]*)" ', block)
  6. if res:
  7. return res[1], res[2]
  8. return "0", ""
  9. res = re.search(field + r' "([^"]*)" ', block)
  10. if res:
  11. return res[1]
  12. res = re.search(field + r" (\w*) ", block)
  13. if res:
  14. return res[1]
  15. return ""
  16. def ignore(block):
  17. s = block.split(" ")
  18. return (s[0], block)
  19. def model_name(block):
  20. return {
  21. "Type": "ModelName",
  22. "Name": get_field("Name", block),
  23. "ModelCodePage": get_field("ModelCodePage", block),
  24. "AutoAccess": get_field("AutoAccess", block),
  25. "UpdateCycle": get_field("UpdateCycle", block),
  26. "ModelStamp": get_field("ModelStamp", block),
  27. "Version": get_field("Version", block),
  28. "ModelCategoryOrderDefault": get_field("ModelCategoryOrderDefault", block),
  29. "ModelOrderedByDefault": get_field("ModelOrderedByDefault", block),
  30. "ModelNonRollupHierarchies": get_field("ModelNonRollupHierarchies", block),
  31. }
  32. def cognos_source(block):
  33. id, name = get_field("CognosSource", block, 2)
  34. return {
  35. "Type": "CognosSource",
  36. "ID": id,
  37. "Name": name,
  38. "SourceType": get_field("SourceType", block),
  39. "SourcePath": get_field("SourcePath", block),
  40. "PackageTimeStamp": get_field("PackageTimeStamp", block),
  41. }
  42. def cognos_package_datasource_connection(block):
  43. id, name = get_field("CognosPackageDatasourceConnection", block, 2)
  44. prs_id, prs_name = get_field("PackageReportSource", block, 2)
  45. return {
  46. "Type": "CognosPackageDatasourceConnection",
  47. "ID": id,
  48. "Name": name,
  49. "PackageReportSource": {
  50. "ID": prs_id,
  51. "Name": prs_name,
  52. },
  53. "CognosPackageConnection": get_field("CognosPackageConnection", block),
  54. "CognosPackageConnectionSignon": get_field(
  55. "CognosPackageConnectionSignon", block
  56. ),
  57. "CognosPackageAlwaysUseTransformerSignon": get_field(
  58. "CognosPackageAlwaysUseTransformerSignon", block
  59. ),
  60. "CognosPackagePowercubeSource": get_field(
  61. "CognosPackagePowercubeSource", block
  62. ),
  63. }
  64. def data_source(block):
  65. id, name = get_field("DataSource", block, 2)
  66. prs_id, prs_name = get_field("PackageReportSource", block, 2)
  67. return {
  68. "Type": "DataSource",
  69. "ID": id,
  70. "Name": name,
  71. "Separator": get_field("Separator", block),
  72. "SourceType": get_field("SourceType", block),
  73. "CharacterSet": get_field("CharacterSet", block),
  74. "DecimalSep": get_field("DecimalSep", block),
  75. "Thousandsep": get_field("Thousandsep", block),
  76. "HasColumns": get_field("Columns", block),
  77. "Timing": get_field("Timing", block),
  78. "PackageReportSource": {
  79. "ID": prs_id,
  80. "Name": prs_name,
  81. },
  82. "AutoSummary": get_field("AutoSummary", block),
  83. "SetCurrent": get_field("SetCurrent", block),
  84. "ServerSource": get_field("ServerSource", block),
  85. "Speed": get_field("Speed", block),
  86. "Presummarized": get_field("Presummarized", block),
  87. "StreamExtractSize": get_field("StreamExtractSize", block),
  88. "Columns": [],
  89. }
  90. def org_name(block):
  91. id, name = get_field("OrgName", block, 2)
  92. return {
  93. "Type": "OrgName",
  94. "ID": id,
  95. "Name": name,
  96. "Origin": get_field("Origin", block),
  97. "Offset": get_field("Offset", block),
  98. "Column": get_field("Column", block),
  99. "Storage": get_field("Storage", block),
  100. "Scale": get_field("Scale", block),
  101. "Size": get_field("Size", block),
  102. "Decimals": get_field("Decimals", block),
  103. "Class": get_field("Class", block),
  104. "InputScale": get_field("InputScale", block),
  105. "TimeArray": get_field("TimeArray", block),
  106. "ColSrcType": get_field("ColSrcType", block),
  107. "Associations": [],
  108. }
  109. def dimension(block):
  110. id, name = get_field("Dimension", block, 2)
  111. return {
  112. "Type": "Dimension",
  113. "ID": id,
  114. "Name": name,
  115. "DimType": get_field("DimType", block),
  116. "EarliestDate": get_field("EarliestDate", block),
  117. "LatestDate": get_field("LatestDate", block),
  118. "ManualPeriods": get_field("ManualPeriods", block),
  119. "DaysInWeek": get_field("DaysInWeek", block),
  120. "NewCatsLock": get_field("NewCatsLock", block),
  121. "ExcludeAutoPartitioning": get_field("ExcludeAutoPartitioning", block),
  122. "DimDefaultCategory": get_field("DimDefaultCategory", block),
  123. "Root": {},
  124. "Levels": [],
  125. "Categories": [],
  126. "SpecialCategories": [],
  127. }
  128. def root(block):
  129. id, name = get_field("Root", block, 2)
  130. return {
  131. "Type": "Root",
  132. "ID": id,
  133. "Name": name,
  134. "Inclusion": get_field("Inclusion", block),
  135. "Lastuse": get_field("Lastuse", block),
  136. "Date": get_field("Date", block),
  137. "Filtered": get_field("Filtered", block),
  138. "Suppressed": get_field("Suppressed", block),
  139. "Sign": get_field("Sign", block),
  140. "HideValue": get_field("HideValue", block),
  141. "IsKeyOrphanage": get_field("IsKeyOrphanage", block),
  142. "IsTruncated": get_field("IsTruncated", block),
  143. "Blanks": get_field("Blanks", block),
  144. "Drill": {},
  145. }
  146. def levels(block):
  147. id, name = get_field("Levels", block, 2)
  148. return {
  149. "Type": "Levels",
  150. "ID": id,
  151. "Name": name,
  152. "Blanks": get_field("Blanks", block),
  153. "Inclusion": get_field("Inclusion", block),
  154. "DateFunction": get_field("DateFunction", block),
  155. "Generate": get_field("Generate", block),
  156. "RefreshLabel": get_field("RefreshLabel", block),
  157. "RefreshDescription": get_field("RefreshDescription", block),
  158. "RefreshShortName": get_field("RefreshShortName", block),
  159. "NewCatsLock": get_field("NewCatsLock", block),
  160. "CatLabFormat": get_field("CatLabFormat", block),
  161. "Timerank": get_field("Timerank", block),
  162. "UniqueCategories": get_field("UniqueCategories", block),
  163. "UniqueMove": get_field("UniqueMove", block),
  164. "Associations": [],
  165. }
  166. def category(block):
  167. id, name = get_field("Category", block, 2)
  168. return {
  169. "Type": "Category",
  170. "ID": id,
  171. "Name": name,
  172. "Parent": get_field("Parent", block),
  173. "Levels": get_field("Levels", block),
  174. "OrderBy": get_field("OrderBy", block),
  175. "Value": get_field("Value", block),
  176. "Label": get_field("Label", block),
  177. "Lastuse": get_field("Lastuse", block),
  178. "SourceValue": get_field("SourceValue", block),
  179. "Date": get_field("Date", block),
  180. "Filtered": get_field("Filtered", block),
  181. "Suppressed": get_field("Suppressed", block),
  182. "Sign": get_field("Sign", block),
  183. "HideValue": get_field("HideValue", block),
  184. "IsKeyOrphanage": get_field("IsKeyOrphanage", block),
  185. "IsTruncated": get_field("IsTruncated", block),
  186. "Blanks": get_field("Blanks", block),
  187. }
  188. def special_category(block):
  189. id, name = get_field("SpecialCategory", block, 2)
  190. return {
  191. "Type": "SpecialCategory",
  192. "ID": id,
  193. "Name": name,
  194. "Parent": get_field("Parent", block),
  195. "Levels": get_field("Levels", block),
  196. "Lastuse": get_field("Lastuse", block),
  197. "Rollup": get_field("Rollup", block),
  198. "TimeAggregate": get_field("TimeAggregate", block),
  199. "RunningPeriods": get_field("RunningPeriods", block),
  200. "TargetOffset": get_field("TargetOffset", block),
  201. "TargetLevel": get_field("TargetLevel", block),
  202. "ContextOffset": get_field("ContextOffset", block),
  203. "DateDrill": get_field("DateDrill", block),
  204. "Primary": get_field("Primary", block),
  205. "Sign": get_field("Sign", block),
  206. }
  207. def map_drills(block):
  208. return {
  209. "Type": "MapDrills",
  210. # "MapDrills MapDrill 1469 "
  211. }
  212. def view_name(block):
  213. id, name = get_field("ViewName", block, 2)
  214. return {
  215. "Type": "ViewName",
  216. "ID": id,
  217. "Name": name,
  218. "ViewType": get_field("Type", block),
  219. "ViewCustomView": get_field("ViewCustomView", block),
  220. }
  221. def associations(block):
  222. id, name = get_field("Associations", block, 2)
  223. return {
  224. "Type": "Associations",
  225. "ID": id,
  226. "Name": name,
  227. "AssociationType": get_field("AssociationType", block),
  228. "AssociationRole": get_field("AssociationRole", block),
  229. "AssociationReferenced": get_field("AssociationReferenced", block),
  230. "SortOrder": get_field("SortOrder", block),
  231. "SortAs": get_field("SortAs", block),
  232. "Parent": "0",
  233. }
  234. def drill(block):
  235. id, name = get_field("Drill", block, 2)
  236. return {
  237. "Type": "Drill",
  238. "ID": id,
  239. "Name": name,
  240. "Label": get_field("Label", block),
  241. "Inclusion": get_field("Inclusion", block),
  242. "Filtered": get_field("Filtered", block),
  243. "Suppressed": get_field("Suppressed", block),
  244. "PrimaryDrill": get_field("PrimaryDrill", block),
  245. "HideValue": get_field("HideValue", block),
  246. "YearBegins": get_field("YearBegins", block),
  247. "PartialWeek": get_field("PartialWeek", block),
  248. "ExtraWeek": get_field("ExtraWeek", block),
  249. "WeekBegins": get_field("WeekBegins", block),
  250. }
  251. def measure(block):
  252. id, name = get_field("Measure", block, 2)
  253. return {
  254. "Type": "Measure",
  255. "ID": id,
  256. "Name": name,
  257. "Missing": get_field("Missing", block),
  258. "IgnoreMissingValue": get_field("IgnoreMissingValue", block),
  259. "Storage": get_field("Storage", block),
  260. "OutPutScale": get_field("OutPutScale", block),
  261. "Decimals": get_field("Decimals", block),
  262. "ReverseSign": get_field("ReverseSign", block),
  263. "IsCurrency": get_field("IsCurrency", block),
  264. "IsFolder": get_field("IsFolder", block),
  265. "Format": get_field("Format", block),
  266. "DrillThrough": get_field("DrillThrough", block),
  267. "Associations": [],
  268. }
  269. def signon(block):
  270. id, name = get_field("Signon", block, 2)
  271. return {
  272. "Type": "Signon",
  273. "ID": id,
  274. "Name": name,
  275. "UserId": get_field("UserId", block),
  276. "PromptForPassword": get_field("PromptForPassword", block),
  277. "EncryptedPW": get_field("EncryptedPW", block),
  278. "AutoLogon": get_field("AutoLogon", block),
  279. "SignonType": get_field("SignonType", block),
  280. }
  281. def dimension_view(block):
  282. id, name = get_field("DimensionView", block, 2)
  283. return {
  284. "Type": "DimensionView",
  285. "ID": id,
  286. "Name": name
  287. # "DimensionView 1463 \"All Categories\" DimensionView 1521 \"All Categories\" DimensionView 1551 \"All Categories\"
  288. # DimensionView 1575 \"All Categories\" DimensionView 1591 \"All Categories\" DimensionView 1651 \"All Categories\"
  289. # DimensionView 1665 \"All Categories\" DimensionView 1693 \"All Categories\" DimensionView 15741 \"All Categories\"
  290. # MeasureInclude 9829 Yes MeasureInclude 10053 Yes MeasureInclude 10309 Yes MeasureInclude 10313 Yes
  291. # MeasureInclude 10317 Yes MeasureInclude 15761 Yes "
  292. }
  293. def allocation_add(block):
  294. # only in DimensionView
  295. return {
  296. "Type": "AllocationAdd",
  297. # "AllocationAdd Measure 9829 Type Default AllocationAdd Measure 10053 Type Default AllocationAdd Measure 10309 Type Default
  298. # AllocationAdd Measure 10313 Type Default AllocationAdd Measure 10317 Type Default AllocationAdd Measure 15761 Type Default "
  299. }
  300. def cube(block):
  301. id, name = get_field("Cube", block, 2)
  302. return {
  303. "Type": "Cube",
  304. "ID": id,
  305. "Name": name,
  306. "MdcFile": get_field("MdcFile", block),
  307. "EncryptedPW": get_field("EncryptedPW", block),
  308. "Status": get_field("Status", block),
  309. "CubeCreation": get_field("CubeCreation", block),
  310. "Optimize": get_field("Optimize", block),
  311. "ConsolidatedRecords": get_field("ConsolidatedRecords", block),
  312. "PartitionSize": get_field("PartitionSize", block),
  313. "PassesNumber": get_field("PassesNumber", block),
  314. "Compress": get_field("Compress", block),
  315. "IncrementalUpdate": get_field("IncrementalUpdate", block),
  316. "ServerCube": get_field("ServerCube", block),
  317. "CubeStamp": get_field("CubeStamp", block),
  318. "CubeCycle": get_field("CubeCycle", block),
  319. "BlockParentTotals": get_field("BlockParentTotals", block),
  320. "Caching": get_field("Caching", block),
  321. "UseAlternateFileName": get_field("UseAlternateFileName", block),
  322. "DeployType": get_field("DeployType", block),
  323. "DeployLocations": get_field("DeployLocations", block),
  324. "DeployToAvailableLocationsAutomatic": get_field(
  325. "DeployToAvailableLocationsAutomatic", block
  326. ),
  327. "DeployCleanupEnabled": get_field("DeployCleanupEnabled", block),
  328. "DeployCleanupNumberOfCubes": get_field("DeployCleanupNumberOfCubes", block),
  329. "DrillThrough": get_field("DrillThrough", block),
  330. "DataSourceSignon": get_field("DataSourceSignon", block),
  331. "PublishEnable": get_field("PublishEnable", block),
  332. "PublishStatus": get_field("PublishStatus", block),
  333. "PublishAllowNullSuppression": get_field("PublishAllowNullSuppression", block),
  334. "PublishAllowMultiEdgeSuppression": get_field(
  335. "PublishAllowMultiEdgeSuppression", block
  336. ),
  337. "PublishAllowAccessToSuppressionOptions": get_field(
  338. "PublishAllowAccessToSuppressionOptions", block
  339. ),
  340. }
  341. def custom_view(block):
  342. id, name = get_field("CustomView", block, 2)
  343. return {
  344. "Type": "CustomView",
  345. "ID": id,
  346. "Name": name,
  347. "DimensionView": [
  348. b for b in re.findall(r'DimensionView (\d+) "([^"]+)"', block)
  349. ],
  350. "MeasureInclude": [
  351. b for b in re.findall(r"MeasureInclude (\d+) (\w+) ", block)
  352. ],
  353. "ChildList": {},
  354. }
  355. def custom_view_child_list(block):
  356. id, name = get_field("CustomViewChildList", block, 2)
  357. return {
  358. "Type": "CustomViewChildList",
  359. "ID": id,
  360. "Name": name,
  361. }
  362. def security_namespace(block):
  363. id, name = get_field("SecurityNameSpace", block, 2)
  364. return {
  365. "Type": "SecurityNameSpace",
  366. "ID": id,
  367. "Name": name,
  368. "SecurityNameSpaceCAMID": get_field("SecurityNameSpaceCAMID", block),
  369. "Objects": [],
  370. }
  371. def security_object(block):
  372. id, name = get_field("SecurityObject", block, 2)
  373. return {
  374. "Type": "SecurityObject",
  375. "ID": id,
  376. "Name": name,
  377. "SecurityObjectDisplayName": get_field("SecurityObjectDisplayName", block),
  378. "SecurityObjectType": get_field("SecurityObjectType", block),
  379. "CustomViewList": get_field("CustomViewList", block),
  380. }
  381. CONVERSION = {
  382. "Name": model_name,
  383. "CognosSource": cognos_source,
  384. "CognosPackageDatasourceConnection": cognos_package_datasource_connection,
  385. "DataSource": data_source,
  386. "OrgName": org_name,
  387. "Dimension": dimension,
  388. "Root": root,
  389. "Drill": drill,
  390. "Levels": levels,
  391. "Associations": associations,
  392. "Category": category,
  393. "SpecialCategory": special_category,
  394. "MapDrills": map_drills,
  395. "ViewName": view_name,
  396. "Measure": measure,
  397. "Signon": signon,
  398. "Cube": cube,
  399. "CustomView": custom_view,
  400. "CustomViewChildList": custom_view_child_list,
  401. "SecurityNameSpace": security_namespace,
  402. "SecurityObject": security_object,
  403. }
  404. def convert_block(block):
  405. block = block.replace("\n", "")
  406. block_type = block.split(" ")[0]
  407. # block_pair = re.findall(r'("[^"]+"|\w+) ', block)
  408. # return (block_type, list(zip((block_pair[::2], block_pair[1::2]))))
  409. if block_type in CONVERSION:
  410. return CONVERSION[block_type](block)
  411. return {"Type": block_type}
  412. def main(filename):
  413. with open(filename, "r", encoding="latin-1") as frh:
  414. mdl_str = frh.read()
  415. mdl_str = re.sub(r"\n+", "\n", mdl_str)
  416. mdl_str = re.sub(r'\nLevels (\d+ [^"])', r"Levels \1", mdl_str)
  417. mdl_str = re.sub(r" Associations ", " \nAssociations ", mdl_str)
  418. mdl_str = re.sub(r'([^ ])""', r"\1'", mdl_str)
  419. mdl_str = re.sub(r'""([^ ])', r"'\1", mdl_str)
  420. tags = "|".join(list(CONVERSION.keys()))
  421. mdl_str = re.sub(r"\n(" + tags + r") ", r"\n\n\1 ", mdl_str)
  422. mdl_blocks = mdl_str.split("\n\n")
  423. converted = [convert_block(b) for b in mdl_blocks]
  424. result = {
  425. "Model": {},
  426. "Connections": [],
  427. "DataSources": [],
  428. "Dimensions": [],
  429. "Measures": [],
  430. "Signons": [],
  431. "CustomViews": [],
  432. "Security": [],
  433. "Cubes": [],
  434. }
  435. types = [c["Type"] for c in converted]
  436. current = None
  437. level_ids = []
  438. for c, t in zip(converted, types):
  439. if t in [""]:
  440. continue
  441. if t in ["Category"] and result["Dimensions"][-1]["Name"] == "Zeit":
  442. continue
  443. if t in ["ModelName"]:
  444. result["Model"] = c
  445. elif t in ["CognosSource", "CognosPackageDatasourceConnection"]:
  446. result["Connections"].append(c)
  447. elif t in ["DataSource"]:
  448. result["DataSources"].append(c)
  449. elif t in ["OrgName"]:
  450. result["DataSources"][-1]["Columns"].append(c)
  451. elif t in ["Dimension"]:
  452. level_ids = []
  453. result["Dimensions"].append(c)
  454. elif t in ["Root"]:
  455. result["Dimensions"][-1]["Root"] = c
  456. elif t in ["Drill"]:
  457. result["Dimensions"][-1]["Root"]["Drill"] = c
  458. elif t in ["Levels"]:
  459. current = c
  460. level_ids.append(c["ID"])
  461. result["Dimensions"][-1]["Levels"].append(c)
  462. elif t in ["Category"]:
  463. if c["Levels"] in level_ids[0:2]:
  464. result["Dimensions"][-1]["Categories"].append(c)
  465. elif t in ["SpecialCategory"]:
  466. result["Dimensions"][-1]["SpecialCategories"].append(c)
  467. elif t in ["Measure"]:
  468. current = c
  469. result["Measures"].append(c)
  470. elif t in ["Associations"]:
  471. c["Parent"] = current["ID"]
  472. current["Associations"].append(c)
  473. for ds in result["DataSources"]:
  474. for col in ds["Columns"]:
  475. if col["Column"] == c["AssociationReferenced"]:
  476. col["Associations"].append(c)
  477. elif t in ["Signon"]:
  478. result["Signons"].append(c)
  479. elif t in ["Cube"]:
  480. result["Cubes"].append(c)
  481. elif t in ["CustomView"]:
  482. result["CustomViews"].append(c)
  483. elif t in ["CustomViewChildList"]:
  484. for cv in result["CustomViews"]:
  485. if cv["ID"] == c["ID"]:
  486. cv["ChildList"] = c
  487. elif t in ["SecurityNameSpace"]:
  488. result["Security"].append(c)
  489. elif t in ["SecurityObject"]:
  490. result["Security"][-1]["Objects"].append(c)
  491. # else:
  492. # print(t, c)
  493. json.dump(result, open(filename[:-4] + ".json", "w"), indent=2)
  494. if __name__ == "__main__":
  495. # main("data/S_Offene_Auftraege.mdl")
  496. main("data/F_Belege_SKR_SKR_Boettche.mdl")