partsdb

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

commit ddd54a958324734f81266f2ee2da32a94fd5c720
parent 4917f5afaa8a8390f7976f93630608b6a5481307
Author: Paco Esteban <paco@e1e0.net>
Date:   Thu, 19 Oct 2023 11:41:21 +0200

we can now add part from template

This is very similar to the update/edit part.
Useful for parts from old stock or dubious origin where I don't have
a MPN and cannot rely on Octopart.
Will also be useful in the future if I want to add mechanical parts and
other stuff to the DB.

Diffstat:
Mpartsdb/database.py | 33+++++++++++++++++++++++++++++++++
Mpartsdb/partsdb.py | 51++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/partsdb/database.py b/partsdb/database.py @@ -50,6 +50,21 @@ INSERT_PART_QUERY = """ ) VALUES (?,?,?,?,?,?,?,?,?,?,?) """ +INSERT_PART_QUERY_FROM_TMPL = """ + INSERT INTO parts + ( + mpn, + manufacturer, + description, + specs, + footprint, + category_id, + storage_id, + quantity, + part_type + ) + VALUES (?,?,?,?,?,?,?,?,?) +""" UPDATE_PART_QUERY = """ UPDATE parts SET @@ -172,6 +187,24 @@ class PartsDB: c.execute(INSERT_PART_QUERY, p) return c.lastrowid + def new_part_from_template(self, part): + with self.conn: + cat_id = self.get_category_by_name(part["cat"])["id"] + sto_id = self.get_storage_by_name(part["storage"])["id"] + c = self.conn.cursor() + update_tuple = ( + part["mpn"], + part["manufacturer"], + part["description"], + part["specs"], + part["footprint"], + cat_id, + sto_id, + part["quantity"], + part["part_type"], + ) + c.execute(INSERT_PART_QUERY_FROM_TMPL, update_tuple) + def get_part(self, part_id): c = self.conn.cursor() c.execute(GET_PART_QUERY, (part_id,)) diff --git a/partsdb/partsdb.py b/partsdb/partsdb.py @@ -21,7 +21,7 @@ db = pdb.PartsDB( ) -def add_part(mpn, quantity, category, storage, part_type): +def add_part_from_octo(mpn, quantity, category, storage, part_type): result = octo.get_part(mpn)["data"]["search"]["results"] if result is None: print(f"Can't find results for {sys.argv[1]} on Octopart") @@ -123,6 +123,36 @@ def add_part(mpn, quantity, category, storage, part_type): db.new_part_history_event(new_id, quantity, "first purchase") +def add_part_from_template(): + new_part_fields = { + "mpn": None, + "manufacturer": None, + "description": None, + "specs": None, + "footprint": None, + "part_type": None, + "cat": None, + "storage": None, + "quantity": None, + } + part_tmp_file = f"/tmp/partsdb_new_part.yaml" + with open(part_tmp_file, mode="w+") as fp: + yaml.dump(new_part_fields, fp) + + # call vim to edit, load the resulting yaml and update db + with open(part_tmp_file, mode="r") as fp: + editor = os.environ.get("EDITOR", "vim") + subprocess.call([editor, fp.name]) + try: + new_part = yaml.safe_load(fp) + db.new_part_from_template(new_part) + except yaml.YAMLError as exc: + print(exc) + + # clean up + os.remove(part_tmp_file) + + def list_parts(category, short): if category == "all": parts = db.list_parts() @@ -259,7 +289,14 @@ def main(): part_sp = ap_part.add_subparsers(dest="subcommand") ### part -> add ap_part_add = part_sp.add_parser("add", help="Add new part from Octopart") - ap_part_add.add_argument("mpn", help="Manufacturer part number") + ap_part_add.add_argument( + "-T", + "--from-template", + action="store_true", + dest="from_template", + help="Add part from YAML template", + ) + ap_part_add.add_argument("-m", "--mpn", dest="mpn", help="Manufacturer part number") ap_part_add.add_argument( "-q", dest="quantity", help="Quantity of new items", type=int ) @@ -380,7 +417,15 @@ def main(): if args.command == "part": if args.subcommand == "add": - add_part(args.mpn, args.quantity, args.category, args.storage, args.type) + if args.from_template: + add_part_from_template() + else: + if not args.mpn: + print("MPN is required if not adding from template") + sys.exit(1) + add_part_from_octo( + args.mpn, args.quantity, args.category, args.storage, args.type + ) elif args.subcommand == "del": delete_part(args.part_id) elif args.subcommand == "get":