mdl_convert.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. from itertools import pairwise
  2. import json
  3. import re
  4. import csv
  5. def get_field(field, block, num=1):
  6. if num == 2:
  7. res = re.search(field + r' (\d+) "([^"]*)" ', block)
  8. if res:
  9. return res[1], res[2]
  10. return "0", ""
  11. res = re.search(field + r' "([^"]*)" ', block)
  12. if res:
  13. return res[1]
  14. res = re.search(field + r" (\w*) ", block)
  15. if res:
  16. return res[1]
  17. return ""
  18. def ignore(block):
  19. s = block.split(" ")
  20. return (s[0], block)
  21. def model_name(block):
  22. return {"Type": "Description", "Decription": block}
  23. # "Name \"Neues Modell\" ModelCodePage \"ibm-5348_P100-1997\" AutoAccess False UpdateCycle 9 ModelStamp 1218210240
  24. # Version \"10.2.6109.304\" ModelCategoryOrderDefault OrderUsePreference ModelOrderedByDefault False
  25. # ModelNonRollupHierarchies False "
  26. def cognos_source(block):
  27. id, name = get_field("CognosSource", block, 2)
  28. return {
  29. "Type": "CognosSource",
  30. "ID": id,
  31. "Name": name,
  32. "SourceType": get_field("SourceType", block),
  33. "SourcePath": get_field("SourcePath", block),
  34. "PackageTimeStamp": get_field("PackageTimeStamp", block),
  35. # "CognosSource 10335 \"GC\" SourceType Package SourcePath \"/content/folder[@name='Package']/package[@name='GC']\"
  36. # PackageTimeStamp \"/content/folder[@name='Package']/package[@name='GC']/model[@name='2020-09-23T14:57:28.424Z']\" "
  37. }
  38. def cognos_package_datasource_connection(block):
  39. id, name = get_field("CognosPackageDatasourceConnection", block, 2)
  40. prs_id, prs_name = get_field("PackageReportSource", block, 2)
  41. return {
  42. "Type": "CognosPackageDatasourceConnection",
  43. "ID": id,
  44. "Name": name,
  45. "PackageReportSource": {
  46. "ID": prs_id,
  47. "Name": prs_name,
  48. },
  49. "CognosPackageConnection": get_field("CognosPackageConnection", block),
  50. "CognosPackageConnectionSignon": get_field(
  51. "CognosPackageConnectionSignon", block
  52. ),
  53. "CognosPackageAlwaysUseTransformerSignon": get_field(
  54. "CognosPackageAlwaysUseTransformerSignon", block
  55. ),
  56. "CognosPackagePowercubeSource": get_field(
  57. "CognosPackagePowercubeSource", block
  58. ),
  59. # "CognosPackageDatasourceConnection 15957 \"3H_AUTOMOBILE\" PackageReportSource 10335 \"GC\"
  60. # CognosPackageConnection \"3H_AUTOMOBILE\"
  61. # CognosPackageConnectionSignon \"3H_AUTOMOBILE\" CognosPackageAlwaysUseTransformerSignon False
  62. # CognosPackagePowercubeSource False "
  63. }
  64. def data_source(block):
  65. id, name = get_field("CognosPackageDatasourceConnection", 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. "Columns": 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. }
  89. def org_name(block):
  90. id, name = get_field("OrgName", block, 2)
  91. return {
  92. "Type": "OrgName",
  93. "ID": id,
  94. "Name": name,
  95. "Origin": get_field("Origin", block),
  96. "Offset": get_field("Offset", block),
  97. "Column": get_field("Column", block),
  98. "Storage": get_field("Storage", block),
  99. "Scale": get_field("Scale", block),
  100. "Size": get_field("Size", block),
  101. "Decimals": get_field("Decimals", block),
  102. "Class": get_field("Class", block),
  103. "InputScale": get_field("InputScale", block),
  104. "TimeArray": get_field("TimeArray", block),
  105. "ColSrcType": get_field("ColSrcType", block),
  106. }
  107. def dimension(block):
  108. id, name = get_field("Dimension", block, 2)
  109. return {
  110. "Type": "Dimension",
  111. "ID": id,
  112. "Name": name,
  113. "DimType": get_field("DimType", block),
  114. "EarliestDate": get_field("EarliestDate", block),
  115. "LatestDate": get_field("LatestDate", block),
  116. "ManualPeriods": get_field("ManualPeriods", block),
  117. "DaysInWeek": get_field("DaysInWeek", block),
  118. "NewCatsLock": get_field("NewCatsLock", block),
  119. "ExcludeAutoPartitioning": get_field("ExcludeAutoPartitioning", block),
  120. "DimDefaultCategory": get_field("DimDefaultCategory", block),
  121. # "Dimension 1463 \"Zeit\" DimType Date EarliestDate 19010101 LatestDate 21001231 ManualPeriods False DaysInWeek 127
  122. # NewCatsLock False ExcludeAutoPartitioning False DimDefaultCategory 0 "
  123. }
  124. def categories(block):
  125. return {
  126. "Type": "Categories",
  127. # "Categories"
  128. }
  129. def root(block):
  130. id, name = get_field("Root", block, 2)
  131. return {
  132. "Type": "Root",
  133. "ID": id,
  134. "Name": name,
  135. "Inclusion": get_field("Inclusion", block),
  136. "Lastuse": get_field("Lastuse", block),
  137. "Date": get_field("Date", block),
  138. "Filtered": get_field("Filtered", block),
  139. "Suppressed": get_field("Suppressed", block),
  140. "Sign": get_field("Sign", block),
  141. "HideValue": get_field("HideValue", block),
  142. "IsKeyOrphanage": get_field("IsKeyOrphanage", block),
  143. "IsTruncated": get_field("IsTruncated", block),
  144. "Blanks": get_field("Blanks", block),
  145. # "Root 1467 \"Zeit\" Inclusion Generate Lastuse 20180820 Date 0 Filtered False
  146. # Suppressed False Sign False HideValue False
  147. # IsKeyOrphanage False IsTruncated False Blanks False Drill 1469 \"Nach Zeit\" Label \"Nach Zeit\" Inclusion Suppress Filtered False
  148. # Suppressed True PrimaryDrill True HideValue False YearBegins 20080101 PartialWeek Split ExtraWeek None WeekBegins Sunday
  149. # Levels 1475 \"Jahr\" Blanks \"( Leerstelle )\" Inclusion Generate DateFunction Year Generate Need RefreshLabel False
  150. # RefreshDescription False RefreshShortName False NewCatsLock False CatLabFormat \"YYYY\" Timerank 10
  151. # UniqueCategories True UniqueMove False Associations 1477 \"Order Date\" AssociationType Type_Query
  152. # AssociationRole Role_Source AssociationReferenced \"Order Date\" Associations 1479 \"Order Date\"
  153. # AssociationContext 1469 AssociationType Type_Query AssociationRole Role_OrderBy
  154. # AssociationReferenced \"Order Date\" SortOrder Default SortAs Ascending "
  155. }
  156. def levels(block):
  157. id, name = get_field("Levels", block, 2)
  158. return {
  159. "Type": "Levels",
  160. "ID": id,
  161. "Name": name,
  162. "Blanks": get_field("Blanks", block),
  163. "Inclusion": get_field("Inclusion", block),
  164. "DateFunction": get_field("DateFunction", block),
  165. "Generate": get_field("Generate", block),
  166. "RefreshLabel": get_field("RefreshLabel", block),
  167. "RefreshDescription": get_field("RefreshDescription", block),
  168. "RefreshShortName": get_field("RefreshShortName", block),
  169. "NewCatsLock": get_field("NewCatsLock", block),
  170. "CatLabFormat": get_field("CatLabFormat", block),
  171. "Timerank": get_field("Timerank", block),
  172. "UniqueCategories": get_field("UniqueCategories", block),
  173. "UniqueMove": get_field("UniqueMove", block),
  174. # "Associations": get_field("Inclusion", block),
  175. # "AssociationType": get_field("Inclusion", block),
  176. # "AssociationRole": get_field("Inclusion", block),
  177. # "AssociationReferenced": get_field("Inclusion", block),
  178. # "Levels 1481 \"Quartal\" Blanks \"( Leerstelle )\" Inclusion Generate DateFunction Quarter Generate All RefreshLabel False
  179. # RefreshDescription False RefreshShortName False NewCatsLock False CatLabFormat \"Q\"\". Q.\"\" YYYY\" Timerank 20
  180. # UniqueCategories True UniqueMove False Associations 1483 \"Order Date\" AssociationType Type_Query
  181. # AssociationRole Role_Source AssociationReferenced \"Order Date\" Associations 1485 \"Order Date\"
  182. # AssociationContext 1469 AssociationType Type_Query AssociationRole Role_OrderBy
  183. # AssociationReferenced \"Order Date\" SortOrder Default SortAs Ascending "
  184. }
  185. def category(block):
  186. return {
  187. "Type": "Category",
  188. # "Category 10555 \"20170101-20171231\" Parent 1469 Levels 1475 OrderBy Drill 1469 Value \"2017\" Label \"2017\"
  189. # Lastuse 20180820 SourceValue \"2017\" Date 20170101 Filtered False Suppressed False Sign False HideValue False
  190. # IsKeyOrphanage False IsTruncated False Blanks False Category 10557 \"20170101-20170331\" Parent 10555 Levels 1481
  191. # OrderBy Drill 1469 Value \"20170101\" Label \"1. Q. 2017\" Lastuse 20180711 SourceValue \"20170101\" Date 20170101
  192. # Filtered False Suppressed False Sign False HideValue False IsKeyOrphanage False IsTruncated False Blanks False
  193. # Category 10559 \"20170101-20170131\" Parent 10557 Levels 1487 OrderBy Drill 1469 Value \"201701\" Label \"Jan./2017\"
  194. # Lastuse 20180711 SourceValue \"201701\" Date 20170101 Filtered False Suppressed False Sign False HideValue False
  195. # IsKeyOrphanage False IsTruncated False Blanks False Category 10561 \"20170101\" Parent 10559 Levels 1493
  196. # OrderBy Drill 1469 Value \"20170101\" Label \"01/01/2017\" Lastuse 20180711 SourceValue \"20170101\" Date 20170101
  197. # Filtered False Suppressed False Sign False HideValue False IsKeyOrphanage False IsTruncated False Blanks False "
  198. }
  199. def special_category(block):
  200. return {
  201. "Type": "SpecialCategory",
  202. # "SpecialCategory 1503 \"M bisher\" Parent 1467 Levels 0 Lastuse 20180820 Rollup True TimeAggregate ToDate RunningPeriods 0
  203. # ToDateLevel \"Monat\" TargetOffset 0 TargetLevel \"Tag\" ContextOffset 0 DateDrill 1469 Primary 11737 Primary 11739
  204. # Primary 11741 Primary 11743 Primary 11745 Primary 11747 Primary 11749 Primary 11751 Primary 11753 Sign False "
  205. }
  206. def map_drills(block):
  207. return {
  208. "Type": "MapDrills",
  209. # "MapDrills MapDrill 1469 "
  210. }
  211. def view_name(block):
  212. return {
  213. "Type": "ViewName",
  214. # "ViewName 1471 \"Alle Kategorien\" Type All ViewCustomView 0 ViewName 1473 \"Dimension auslassen\" Type Omit
  215. # ViewCustomView 0 Dimension 1521 \"AH-Gruppe\" DimType Regular NewCatsLock False ExcludeAutoPartitioning False
  216. # DimDefaultCategory 0 "
  217. }
  218. def associations(block):
  219. return {
  220. "Type": "Associations",
  221. # "Associations 15065 \"Hauptbetrieb_Name\" AssociationType Type_Query AssociationRole Role_Label
  222. # AssociationReferenced \"Hauptbetrieb_Name\" Associations 15069 \"Hauptbetrieb_ID\"
  223. # AssociationContext 1525 AssociationType Type_Query AssociationRole Role_OrderBy
  224. # AssociationReferenced \"Hauptbetrieb_ID\" SortOrder Text SortAs Ascending "
  225. }
  226. def drill(block):
  227. id, name = get_field("Drill", block, 2)
  228. return {
  229. "Type": "Drill",
  230. "ID": id,
  231. "Name": name,
  232. "Label": get_field("Label", block),
  233. "Inclusion": get_field("Inclusion", block),
  234. "Filtered": get_field("Filtered", block),
  235. "Suppressed": get_field("Suppressed", block),
  236. "PrimaryDrill": get_field("PrimaryDrill", block),
  237. "HideValue": get_field("HideValue", block),
  238. "YearBegins": get_field("YearBegins", block),
  239. "PartialWeek": get_field("PartialWeek", block),
  240. "ExtraWeek": get_field("ExtraWeek", block),
  241. "WeekBegins": get_field("WeekBegins", block),
  242. # "Drill 1595 \"Nach Marke\" Inclusion Suppress Filtered False Suppressed True PrimaryDrill True HideValue False
  243. # Levels 1601 \"Marke\" Blanks \"( Leerstelle )\"
  244. # DateFunction None Generate None RefreshLabel False RefreshDescription False RefreshShortName False NewCatsLock False Timerank 0
  245. # UniqueCategories False UniqueMove False
  246. # Associations 1603 \"Fabrikat\" AssociationType Type_Query AssociationRole Role_Source AssociationReferenced \"Fabrikat\" "
  247. }
  248. def measure(block):
  249. return {
  250. "Type": "Measure",
  251. # "Measure 10053 \"DG\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8
  252. # ReverseSign False IsCurrency False
  253. # IsFolder False Format \"#,##0~0\" DrillThrough False EndList
  254. # Associations 10055 \"DG\" AssociationType Type_Query AssociationRole Role_Source AssociationReferenced \"DG\" "
  255. }
  256. def signon(block):
  257. return {
  258. "Type": "Signon",
  259. # "Signon 15673 \"GC_CARLO\" UserId \"gaps\" PromptForPassword False
  260. # EncryptedPW \"*1*0154377D72534C4B5F384F556F5B7970286A59373F70255D63D4EDE5BC9A7FD45994\" \"AC2C0B8CE18548\"
  261. # AutoLogon False SignonType \"DataSource\" Signon 15917 \"Global1\" UserId \"Global1\" PromptForPassword False
  262. # EncryptedPW \"*1*013B396846296D72232C62274C312B48432B464B52705B2147BC0680EA66C628A0FE\" \"A70FDB4177ACBA\"
  263. # AutoLogon True SignOnNamespace \"CognosEx\" SignonType \"Cognos\" "
  264. }
  265. def dimension_view(block):
  266. return {
  267. "Type": "DimensionView",
  268. # "DimensionView 1463 \"All Categories\" DimensionView 1521 \"All Categories\" DimensionView 1551 \"All Categories\"
  269. # DimensionView 1575 \"All Categories\" DimensionView 1591 \"All Categories\" DimensionView 1651 \"All Categories\"
  270. # DimensionView 1665 \"All Categories\" DimensionView 1693 \"All Categories\" DimensionView 15741 \"All Categories\"
  271. # MeasureInclude 9829 Yes MeasureInclude 10053 Yes MeasureInclude 10309 Yes MeasureInclude 10313 Yes
  272. # MeasureInclude 10317 Yes MeasureInclude 15761 Yes "
  273. }
  274. def allocation_add(block):
  275. return {
  276. "Type": "AllocationAdd",
  277. # "AllocationAdd Measure 9829 Type Default AllocationAdd Measure 10053 Type Default AllocationAdd Measure 10309 Type Default
  278. # AllocationAdd Measure 10313 Type Default AllocationAdd Measure 10317 Type Default AllocationAdd Measure 15761 Type Default "
  279. }
  280. def cube(block):
  281. return {
  282. "Type": "Cube",
  283. }
  284. CONVERSION = {
  285. "Name": model_name,
  286. "CognosSource": cognos_source,
  287. "CognosPackageDatasourceConnection": cognos_package_datasource_connection,
  288. "DataSource": data_source,
  289. "OrgName": org_name,
  290. "Dimension": dimension,
  291. "Categories": categories,
  292. "Root": root,
  293. "Category": category,
  294. "SpecialCategory": special_category,
  295. "Levels": levels,
  296. "MapDrills": map_drills,
  297. "ViewName": view_name,
  298. "Drill": drill,
  299. "Measure": measure,
  300. "Signon": signon,
  301. "DimensionView": dimension_view,
  302. "Cube": cube,
  303. }
  304. def convert_block(block):
  305. block = block.replace("\n", "")
  306. block_type = block.split(" ")[0]
  307. # block_pair = re.findall(r'("[^"]+"|\w+) ', block)
  308. # return (block_type, list(zip((block_pair[::2], block_pair[1::2]))))
  309. if block_type in CONVERSION:
  310. return CONVERSION[block_type](block)
  311. return block_type
  312. def main(filename):
  313. with open(filename, "r") as frh:
  314. mdl_str = frh.read()
  315. mdl_str = re.sub(r"\n+", "\n", mdl_str)
  316. tags = "|".join(list(CONVERSION.keys()))
  317. mdl_str = re.sub(r"\n(" + tags + r") ", r"\n\n\1 ", mdl_str)
  318. mdl_blocks = mdl_str.split("\n\n")
  319. result = [convert_block(b) for b in mdl_blocks]
  320. json.dump(result, open(filename[:-4] + ".json", "w"), indent=2)
  321. if __name__ == "__main__":
  322. main("data/S_Offene_Auftraege.mdl")