partsdb

electronic parts inventory
git clone https://git.e1e0.net/partsdb.git
Log | Files | Refs | README | LICENSE

helpers.py (5676B)


      1 #!/usr/bin/env python3
      2 # -*- coding: utf-8 -*-
      3 # vim:fenc=utf-8
      4 
      5 import json
      6 import subprocess
      7 import tempfile
      8 import time
      9 
     10 
     11 def print_parts_list(parts, output="full"):
     12     if output == "short":
     13         _list_ascii_short(parts)
     14     if output == "full":
     15         _list_ascii(parts)
     16     if output == "json":
     17         _list_json(parts)
     18 
     19 
     20 def _list_ascii(parts):
     21     # max takes an iterable and key is a function where iterables are
     22     # passed and comparison performed, so we look at the longest desc to
     23     # get the lenght of the field.  We also check if the header is longer,
     24     # the result is whatever is longer
     25     l_pn = len(max(parts, key=lambda k: len(k["pn"]))["pn"])
     26     l_cat = len(max(parts, key=lambda k: len(k["cname"]))["cname"])
     27     l_man = len(max(parts, key=lambda k: len(k["manufacturer"]))["manufacturer"])
     28     l_desc = len(max(parts, key=lambda k: len(k["description"]))["description"])
     29     l_cat = l_cat if l_cat > len("Category") else len("Category")
     30     l_man = l_man if l_man > len("Manufacturer") else len("Manufacturer")
     31     l_desc = l_desc if l_desc > len("Description") else len("Description")
     32 
     33     header = (
     34         f"| {'ID':5} | {'PN':{l_pn}} | "
     35         f"{'Category':{l_cat}} | "
     36         f"{'Manufacturer':{l_man}} | "
     37         f"{'Description':{l_desc}} | "
     38         f"{'Type':4} | "
     39         f"{'Footp':6} | "
     40         f"{'Qty':4} |"
     41     )
     42     for i, p in enumerate(parts):
     43         if i % 25 == 0:
     44             print("-" * len(header))
     45             print(header)
     46             print("-" * len(header))
     47         print(
     48             f"| {p['id']:<5} | {p['pn']:{l_pn}} | "
     49             f"{p['cname']:{l_cat}} | "
     50             f"{_sanitize_value(p['manufacturer']):{l_man}} | "
     51             f"{_sanitize_value(p['description']):{l_desc}} | "
     52             f"{_sanitize_value(p['part_type'])[0:3]:4} | "
     53             f"{_sanitize_value(p['footprint'])[0:5]:6} | "
     54             f"{p['quantity']:4} |"
     55         )
     56 
     57 
     58 def _list_ascii_short(parts):
     59     header = (
     60         f"| {'ID':4} | "
     61         f"{'Category':8} | "
     62         f"{'PN':10} | "
     63         f"{'Manufacturer':16} | "
     64         f"{'Description':25} |"
     65     )
     66     for i, p in enumerate(parts):
     67         if i % 25 == 0:
     68             print("-" * 79)
     69             print(header)
     70             print("-" * 79)
     71         print(
     72             f"| {p['id']:<4} | "
     73             f"{p['cname'][0:7]:8} | "
     74             f"{_sanitize_value(p['pn'])[0:9]:10} | "
     75             f"{_sanitize_value(p['manufacturer'])[0:15]:16} | "
     76             f"{_sanitize_value(p['description'])[0:24]:25} |"
     77         )
     78 
     79 
     80 def _list_json(parts):
     81     p = [dict(zip(part.keys(), part)) for part in parts]
     82     print(json.dumps({"parts": p}))
     83 
     84 
     85 def print_part(p, history, output="full"):
     86     if output == "full":
     87         _part_ascii(p, history)
     88     if output == "json":
     89         _part_json(p, history)
     90 
     91 
     92 def _part_ascii(p, history):
     93     print(f"PN: {p['pn']}\tManufacturer: {p['manufacturer']}\tMPN: {p['mpn']}")
     94     print(
     95         f"Category: {p['cat']}\tType: {p['part_type']}" f"\tFootprint: {p['footprint']}"
     96     )
     97     print(f"Storage: {p['storage']}")
     98     print(f"Created: {p['insert_date']}" f"\tUpdated: {p['update_date']}\n")
     99     print(f"Description:\n{p['description']}\n")
    100     print(f"Specs:\n{p['specs']}")
    101 
    102     if p["datasheet"] is not None:
    103         print("This part has a datasheet available.")
    104     if p["image"] is not None:
    105         print("This part has an image available.")
    106 
    107     print(f"\nQuantity: {p['quantity']}")
    108     # here should go the historical data.
    109     if history:
    110         print("History:")
    111         for h in history:
    112             print(f"{h['insert_date']} | " f"{h['movement']:4} | " f"{h['mcomment']}")
    113 
    114 
    115 def _part_json(part, history):
    116     part = dict(zip(part.keys(), part))
    117     # remove bytes data if present.  For now is useless in this output.
    118     del part["datasheet"]
    119     del part["image"]
    120 
    121     part["history"] = [dict(zip(h.keys(), h)) for h in history]
    122 
    123     print(json.dumps({"part": part}))
    124 
    125 
    126 def _sanitize_value(value):
    127     if value is None:
    128         return "-"
    129     return value
    130 
    131 
    132 def open_file(content, extension):
    133     with tempfile.NamedTemporaryFile(suffix=extension) as f:
    134         f.write(content)
    135         subprocess.Popen(["xdg-open", f.name], start_new_session=True)
    136         time.sleep(2)
    137 
    138 
    139 def html_main_index(dest_folder, categories, storages, env):
    140     tpl = env.get_template("index.html")
    141     with open(f"{dest_folder}/index.html", "w") as f:
    142         f.write(tpl.render(cat=categories, sto=storages))
    143 
    144 
    145 def html_category_index(dest_folder, category, parts, env):
    146     tpl = env.get_template("cat.html")
    147     with open(f"{dest_folder}/cat_list_{category['id']}.html", "w") as f:
    148         f.write(tpl.render(category=category, parts=parts))
    149 
    150 
    151 def html_storage_index(dest_folder, storage, parts, env):
    152     tpl = env.get_template("storage.html")
    153     with open(f"{dest_folder}/storage_{storage['id']}.html", "w") as f:
    154         f.write(tpl.render(storage=storage, parts=parts))
    155 
    156 
    157 def html_part(dest_folder, part, part_history, env):
    158     tpl = env.get_template("part.html")
    159     with open(f"{dest_folder}/part_{part['id']}.html", "w") as f:
    160         f.write(tpl.render(part=part, history=part_history))
    161 
    162 
    163 def html_css(dest_folder, env):
    164     tpl = env.get_template("style.css")
    165     with open(f"{dest_folder}/style.css", "w") as f:
    166         f.write(tpl.render())
    167 
    168 
    169 def html_attachments(dest_folder, part_id, datasheet, image):
    170     if datasheet["datasheet"] is not None:
    171         with open(f"{dest_folder}/part_datasheet_{part_id}.pdf", "wb") as f:
    172             f.write(datasheet["datasheet"])
    173     if image["image"] is not None:
    174         with open(f"{dest_folder}/part_image_{part_id}.jpg", "wb") as f:
    175             f.write(image["image"])