Source code for mib_generator.generation.gener_doc

"""This module enables generation of a ``.docx`` file which documents in a human-readable way what was put in MIB tables for a
given set of Tm and Tc packets.

The only (important) method in this module builds up the ``.docx`` file using the not so powerful ``python-docx`` library.
"""

from docx import Document
from docx.enum.table import WD_ALIGN_VERTICAL
from docx.oxml import parse_xml
from docx.oxml.ns import nsdecls
from docx.shared import Cm, Inches

import mib_generator.parsing.load as load


[docs] def gen_doc(Tm_packets=[], Tc_packets=[]): """Create a ``.docx`` document which sketches out what entries are in each of the Tm and Tc packets in the passed list. This method goes through all passed Tm and Tc packets and for each adds an entry to the created ``.docx`` document including basic info about the packet and a table of entries within it. The format of the output tries to adhere to a standard scheme of an ICD document used normally for these purposes. Args: Tm_packets (list): List of Tm-packets, each of type :obj:`mib_generator.construction.TM_packet.TM_packet`, from which the document is to be generated. Tc_packets (list): List of Tc-packets, each of type :obj:`mib_generator.construction.TC_packet.TC_packet`, from which the document is to be generated. """ document = Document() if Tm_packets: document.add_heading("Telemetry packets", 1) for i in Tm_packets: h = document.add_heading("", 2) try: t = str(i.pid["PID_TYPE"]) st = str(i.pid["PID_STYPE"]) if int(i.pid["PID_PI1_VAL"]) > 0: si = ",SID=" + str(i.pid["PID_PI1_VAL"]) else: si = "" desc = i.pid["PID_DESCR"] except: t = "?" st = "?" si = "" desc = "____" h.add_run("TM[" + t + "," + st + si + "] " + desc).italic = True try: document.add_paragraph( "APID: " + str(i.pid["PID_APID"]), style="List Bullet" ) except: document.add_paragraph("APID: ?", style="List Bullet") try: document.add_paragraph( "MIB name: " + i.tpcf["TPCF_NAME"], style="List Bullet" ) except: document.add_paragraph("MIB name: ?", style="List Bullet") try: document.add_paragraph( "MIB SPID: " + str(i.pid["PID_SPID"]), style="List Bullet" ) except: document.add_paragraph("MIB SPID: ?", style="List Bullet") table = document.add_table(rows=1, cols=4) table.style = "Table Grid" table.autofit = True table.rows[0].cells[0].paragraphs[0].add_run("Byte").bold = True table.rows[0].cells[1].paragraphs[0].add_run("ID").bold = True table.rows[0].cells[2].paragraphs[0].add_run("Size in bites").bold = True table.rows[0].cells[3].paragraphs[0].add_run("Description").bold = True table.columns[0].width = Cm(3.2) table.columns[1].width = Cm(3.2) table.columns[2].width = Cm(3.2) table.columns[3].width = Cm(5.9) for l in range(4): table.rows[0].cells[l]._tc.get_or_add_tcPr().append( parse_xml(r'<w:shd {} w:fill="C7D9F1"/>'.format(nsdecls("w"))) ) table.rows[0].cells[l].vertical_alignment = WD_ALIGN_VERTICAL.CENTER for l in range(len(i.plf)): row = table.add_row().cells row[0].text = to_bytes(i.positions[l]) row[1].text = i.pcf[l]["PCF_NAME"] row[2].text = str(i.positions[l + 1] - i.positions[l]) row[3].text = i.pcf[l]["PCF_DESCR"] for k in range(4): row[k].vertical_alignment = WD_ALIGN_VERTICAL.CENTER document.add_paragraph() if Tc_packets: document.add_heading("Telecommand packets", 1) for i in Tc_packets: h = document.add_heading("", 2) try: t = str(i.ccf["CCF_TYPE"]) st = str(i.ccf["CCF_STYPE"]) desc = i.ccf["CCF_DESCR"] except: t = "?" st = "?" desc = "____" h.add_run("TC[" + t + "," + st + "] " + desc).italic = True try: if str(i.ccf["CCF_APID"]): document.add_paragraph( "APID: " + str(i.ccf["CCF_APID"]), style="List Bullet" ) else: document.add_paragraph("APID: ?", style="List Bullet") except: document.add_paragraph("APID: ?", style="List Bullet") try: document.add_paragraph( "MIB name: " + str(i.ccf["CCF_CNAME"]), style="List Bullet" ) except: document.add_paragraph("MIB name: ?", style="List Bullet") table = document.add_table(rows=1, cols=5) table.style = "Table Grid" table.autofit = True table.rows[0].cells[0].paragraphs[0].add_run("Byte").bold = True table.rows[0].cells[1].paragraphs[0].add_run("ID").bold = True table.rows[0].cells[2].paragraphs[0].add_run("Size in bites").bold = True table.rows[0].cells[3].paragraphs[0].add_run("Type").bold = True table.rows[0].cells[4].paragraphs[0].add_run("Description").bold = True table.columns[0].width = Cm(2.7) table.columns[1].width = Cm(2.7) table.columns[2].width = Cm(2.7) table.columns[3].width = Cm(2.7) table.columns[4].width = Cm(4.8) for l in range(5): table.rows[0].cells[l]._tc.get_or_add_tcPr().append( parse_xml(r'<w:shd {} w:fill="C7D9F1"/>'.format(nsdecls("w"))) ) table.rows[0].cells[l].vertical_alignment = WD_ALIGN_VERTICAL.CENTER for l in range(len(i.cdf)): row = table.add_row().cells row[0].text = to_bytes(i.positions[l]) row[1].text = i.cdf[l]["CDF_PNAME"] if not row[1].text: row[1].text = i.entries[l].name row[2].text = str(i.positions[l + 1] - i.positions[l]) row[3].text = str(i.entries[l].type) row[4].text = i.cdf[l]["CDF_DESCR"] for k in range(4): row[k].vertical_alignment = WD_ALIGN_VERTICAL.CENTER document.add_paragraph() return document
[docs] def to_bytes(bits): """Give the number of bits in bytes and in some meaning full format. Calculates how many bytes are in the passed bits, how many residual bits, and puts together this information into a meaningful-looking string. Args: bits (int): Numeber of bits to be "translated". Returns: str: The number of bits in bytes and residual bits in understandable form. """ byt = int(bits / 8) bit = bits - byt * 8 if bit == 0: return str(byt) elif bit == 1: return str(byt) + " (+ " + str(bit) + " bit)" else: return str(byt) + " (+ " + str(bit) + " bits)"