partsdb

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

commit 697f06426eac30c81defb0bb53ec6b22705a337a
parent 68a5ae05516510fa86b6aef4382bef886fb668be
Author: Paco Esteban <paco@e1e0.net>
Date:   Thu, 25 Nov 2021 19:34:42 +0100

linting stuff

Diffstat:
Mpartsdb/database.py | 18++++++++----------
Mpartsdb/helpers.py | 34++++++++++++++--------------------
Mpartsdb/octopart.py | 15++++++---------
Mpartsdb/partsdb.py | 93+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
4 files changed, 81 insertions(+), 79 deletions(-)

diff --git a/partsdb/database.py b/partsdb/database.py @@ -5,7 +5,6 @@ import sqlite3 from sqlite3 import Error - GET_CATEGORIES_QUERY = "SELECT id, name FROM categories" GET_STORAGES_QUERY = "SELECT id, name FROM storages" LIST_PARTS_QUERY = """ @@ -83,7 +82,6 @@ GET_DATASHEET_QUERY = "SELECT datasheet FROM parts WHERE id = ?" class PartsDB(): - def __init__(self, database): try: self.conn = sqlite3.connect(database) @@ -122,12 +120,12 @@ class PartsDB(): def get_part(self, part_id): c = self.conn.cursor() - c.execute(GET_PART_QUERY, (part_id,)) + c.execute(GET_PART_QUERY, (part_id, )) return c.fetchone() def get_part_by_mpn(self, mpn): c = self.conn.cursor() - c.execute(GET_PART_BY_MPN_QUERY, (mpn,)) + c.execute(GET_PART_BY_MPN_QUERY, (mpn, )) return c.fetchone() def search_parts(self, term): @@ -137,7 +135,7 @@ class PartsDB(): def get_part_history(self, part_id): c = self.conn.cursor() - c.execute(GET_HISTORY_QUERY, (part_id,)) + c.execute(GET_HISTORY_QUERY, (part_id, )) return c.fetchall() def new_part_history_event(self, part_id, movement, comment): @@ -148,7 +146,7 @@ class PartsDB(): def update_part_qty(self, part_id, movement): with self.conn: c = self.conn.cursor() - c.execute(GET_PART_QTY, (part_id,)) + c.execute(GET_PART_QTY, (part_id, )) qty = c.fetchone()['quantity'] qty = qty + movement c.execute(UPDATE_PART_QTY_QUERY, (qty, part_id)) @@ -156,17 +154,17 @@ class PartsDB(): def delete_part(self, part_id): with self.conn: c = self.conn.cursor() - c.execute(DELETE_HISTORY_QUERY, (part_id,)) - c.execute(DELETE_PART_QUERY, (part_id,)) + c.execute(DELETE_HISTORY_QUERY, (part_id, )) + c.execute(DELETE_PART_QUERY, (part_id, )) def get_image(self, part_id): c = self.conn.cursor() - c.execute(GET_IMAGE_QUERY, (part_id,)) + c.execute(GET_IMAGE_QUERY, (part_id, )) return c.fetchone() def get_datasheet(self, part_id): c = self.conn.cursor() - c.execute(GET_DATASHEET_QUERY, (part_id,)) + c.execute(GET_DATASHEET_QUERY, (part_id, )) return c.fetchone() def close(self): diff --git a/partsdb/helpers.py b/partsdb/helpers.py @@ -23,12 +23,11 @@ def _list_ascii(parts): # get the lenght of the field. We also check if the header is longer, # the result is whatever is longer l_pn = len(max(parts, key=lambda k: len(k['pn']))['pn']) - l_cat = len(max(parts, - key=lambda k: len(k['cname']))['cname']) - l_man = len(max(parts, - key=lambda k: len(k['manufacturer']))['manufacturer']) - l_desc = len(max(parts, - key=lambda k: len(k['description']))['description']) + l_cat = len(max(parts, key=lambda k: len(k['cname']))['cname']) + l_man = len( + max(parts, key=lambda k: len(k['manufacturer']))['manufacturer']) + l_desc = len( + max(parts, key=lambda k: len(k['description']))['description']) l_cat = l_cat if l_cat > len('Category') else len('Category') l_man = l_man if l_man > len('Manufacturer') else len('Manufacturer') l_desc = l_desc if l_desc > len('Description') else len('Description') @@ -39,21 +38,19 @@ def _list_ascii(parts): f"{'Description':{l_desc}} | " f"{'Type':4} | " f"{'Footp':6} | " - f"{'Qty':4} |" - ) + f"{'Qty':4} |") for i, p in enumerate(parts): if i % 25 == 0: - print("-"*len(header)) + print("-" * len(header)) print(header) - print("-"*len(header)) + print("-" * len(header)) print(f"| {p['id']:<5} | {p['pn']:{l_pn}} | " f"{p['cname']:{l_cat}} | " f"{_sanitize_value(p['manufacturer']):{l_man}} | " f"{_sanitize_value(p['description']):{l_desc}} | " f"{_sanitize_value(p['part_type'])[0:3]:4} | " f"{_sanitize_value(p['footprint'])[0:5]:6} | " - f"{p['quantity']:4} |" - ) + f"{p['quantity']:4} |") def _list_ascii_short(parts): @@ -61,19 +58,17 @@ def _list_ascii_short(parts): f"{'Category':8} | " f"{'PN':10} | " f"{'Manufacturer':16} | " - f"{'Description':25} |" - ) + f"{'Description':25} |") for i, p in enumerate(parts): if i % 25 == 0: - print("-"*79) + print("-" * 79) print(header) - print("-"*79) + print("-" * 79) print(f"| {p['id']:<4} | " f"{p['cname'][0:7]:8} | " f"{_sanitize_value(p['pn'])[0:9]:10} | " f"{_sanitize_value(p['manufacturer'])[0:15]:16} | " - f"{_sanitize_value(p['description'])[0:24]:25} |" - ) + f"{_sanitize_value(p['description'])[0:24]:25} |") def _list_json(parts): @@ -93,8 +88,7 @@ def _part_ascii(p, history): print(f"Category: {p['cat']}\tType: {p['part_type']}" f"\tFootprint: {p['footprint']}") print(f"Storage: {p['storage']}") - print(f"Created: {p['insert_date']}" - f"\tUpdated: {p['update_date']}\n") + print(f"Created: {p['insert_date']}" f"\tUpdated: {p['update_date']}\n") print(f"Description:\n{p['description']}\n") print(f"Specs:\n{p['specs']}") diff --git a/partsdb/octopart.py b/partsdb/octopart.py @@ -7,7 +7,6 @@ import sys import urllib.error import urllib.request - GET_PARTS_GRAPHQL_QUERY = ''' query MyPartSearch($q: String!, $filters: Map) { search(q: $q, filters: $filters, limit: 5) { @@ -58,7 +57,6 @@ GET_PARTS_GRAPHQL_QUERY = ''' # copy pasted from: https://github.com/prisma-labs/python-graphql-client/blob/master/graphqlclient/client.py class OctopartClient(): - def __init__(self, token): self.endpoint = 'https://octopart.com/api/v4/endpoint' if token is None: @@ -70,10 +68,11 @@ class OctopartClient(): return self._send(query, variables) def _send(self, query, variables): - data = {'query': query, - 'variables': variables} - headers = {'Accept': 'application/json', - 'Content-Type': 'application/json'} + data = {'query': query, 'variables': variables} + headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } if self.token is not None: headers['token'] = '{}'.format(self.token) @@ -96,9 +95,7 @@ class OctopartClient(): # "manufacturer_id": ["370"] # } # } - parameters = { - "q": mpn - } + parameters = {"q": mpn} resp = self.execute(query, parameters) # print(json.dumps(json.loads(resp), indent = 2)) diff --git a/partsdb/partsdb.py b/partsdb/partsdb.py @@ -15,8 +15,9 @@ from partsdb import octopart as oc __version__ = 'v1.3.0' octo = oc.OctopartClient(os.getenv('OCTOPART_TOKEN', None)) -db = pdb.PartsDB(os.getenv('PARTSDB_FILE', - f"{os.getenv('HOME')}/.local/share/partsdb/parts.db")) +db = pdb.PartsDB( + os.getenv('PARTSDB_FILE', + f"{os.getenv('HOME')}/.local/share/partsdb/parts.db")) def add_part(mpn, quantity, category, storage, part_type): @@ -27,7 +28,7 @@ def add_part(mpn, quantity, category, storage, part_type): # list results from Octopart and pick one for i, r in enumerate(result): - print('-'*79) + print('-' * 79) print(f"{i}\t{r['part']['manufacturer']['name']}" f"\t{r['part']['mpn']}") print(f"\t{r['part']['short_description']}") @@ -89,7 +90,8 @@ def add_part(mpn, quantity, category, storage, part_type): datasheet = p['best_datasheet']['url'] elif 'document_collections' in p: for d in p['document_collections'][0]['documents']: - if d['mime_type'] == 'application/pdf' and d['name'] == 'Datasheet': + if (d['mime_type'] == 'application/pdf' + and d['name'] == 'Datasheet'): datasheet = d['url'] headers = {} headers['User-Agent'] = "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:48.0) Gecko/20100101 Firefox/48.0" @@ -104,17 +106,8 @@ def add_part(mpn, quantity, category, storage, part_type): image = urllib.request.urlopen(req).read() part = [ - p['mpn'], - p['mpn'], - p['manufacturer']['name'], - p['short_description'], - specs, - footprint, - category, - storage, - quantity, - datasheet, - image, + p['mpn'], p['mpn'], p['manufacturer']['name'], p['short_description'], + specs, footprint, category, storage, quantity, datasheet, image, part_type ] new_id = db.new_part(part) @@ -176,10 +169,8 @@ def adjust_stock(part_id, stock_mod, comment): def export_db(dest_folder): - env = Environment( - loader=PackageLoader('partsdb.exports', 'templates'), - autoescape=select_autoescape(['html', 'xml']) - ) + env = Environment(loader=PackageLoader('partsdb.exports', 'templates'), + autoescape=select_autoescape(['html', 'xml'])) categories = db.get_categories() helpers.html_main_index(dest_folder, categories, env) for c in categories: @@ -199,15 +190,17 @@ def export_db(dest_folder): def list_categories(): categories = db.get_categories() print("ID\tName") - print("-"*40) + print("-" * 40) for c in categories: print(f"{c['id']}\t{c['name']}") def main(): ap = argparse.ArgumentParser() - ap.add_argument('--version', '-v', action='version', - version='%(prog)s '+__version__) + ap.add_argument('--version', + '-v', + action='version', + version='%(prog)s ' + __version__) # Place for global options here # parser.add_argument(...) # And then the commands @@ -215,38 +208,57 @@ def main(): # add ap_add = asp.add_parser("add", help="Add new part from Octopart") ap_add.add_argument("mpn", help="Manufacturer part number") - ap_add.add_argument("-q", dest='quantity', - help="Quantity of new items", type=int) - ap_add.add_argument("-c", dest='category', - help="Which categoryId it belongs to", type=int) - ap_add.add_argument("-s", dest='storage', - help="Which storageId it belongs to", type=int) - ap_add.add_argument("-t", dest='type', choices=['smd', 'th'], - default='none', help="Trhough-hole of smd ?") + ap_add.add_argument("-q", + dest='quantity', + help="Quantity of new items", + type=int) + ap_add.add_argument("-c", + dest='category', + help="Which categoryId it belongs to", + type=int) + ap_add.add_argument("-s", + dest='storage', + help="Which storageId it belongs to", + type=int) + ap_add.add_argument("-t", + dest='type', + choices=['smd', 'th'], + default='none', + help="Trhough-hole of smd ?") # cat - ap_cat = asp.add_parser("cat", help="List categories") + asp.add_parser("cat", help="List categories") # list ap_list = asp.add_parser("list", help="List all parts from a category (or all)") ap_list.add_argument("category", help="Category Name or ID") - ap_list.add_argument("-o", dest='output', - choices=['full', 'short', 'json'], default='full', + ap_list.add_argument("-o", + dest='output', + choices=['full', 'short', 'json'], + default='full', help="Short output") # search ap_search = asp.add_parser("search", help="Search for parts") ap_search.add_argument("search_term", help="Term to search for") - ap_search.add_argument("-o", dest='output', - choices=['full', 'short', 'json'], default='full', + ap_search.add_argument("-o", + dest='output', + choices=['full', 'short', 'json'], + default='full', help="Short output") # get ap_get = asp.add_parser("get", help="Get all details for a part") ap_get.add_argument("part_id", help="Part Id", type=int) - ap_get.add_argument("-d", dest='datasheet', action='store_true', + ap_get.add_argument("-d", + dest='datasheet', + action='store_true', help="Open datasheet if available.") - ap_get.add_argument("-i", dest='image', action='store_true', + ap_get.add_argument("-i", + dest='image', + action='store_true', help="Open image if available.") - ap_get.add_argument("-o", dest='output', - choices=['full', 'json'], default='full', + ap_get.add_argument("-o", + dest='output', + choices=['full', 'json'], + default='full', help="Short output") # delete ap_delete = asp.add_parser("delete", help="Delete a part") @@ -255,7 +267,8 @@ def main(): ap_stock = asp.add_parser("stock", help="Modifies a part stock") ap_stock.add_argument("part_id", help="Part Id", type=int) ap_stock.add_argument("stock_mod", - help="Stock modifier (+ or -) int", type=int) + help="Stock modifier (+ or -) int", + type=int) ap_stock.add_argument("comment", help="Reason for the stock mod") # export ap_export = asp.add_parser("export", help="Exports DB to HTML")