Skip to content

Commit

Permalink
Merge pull request #149 from T0jan/parameter-handling
Browse files Browse the repository at this point in the history
Add proxy support
  • Loading branch information
eeintech committed Apr 24, 2023
2 parents 74c19e6 + f5cf715 commit 8e0ae07
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 12 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ Note that each time you enable the "Add" permission to an object, InvenTree auto
2. Click on "Settings > Supplier > Mouser" and fill in the Mouser part search API key
3. Click on "Settings > Supplier > Element14" and fill in the Element14 product search API key (key is shared with Farnell and Newark)
4. Click on "Settings > KiCad", browse to the location where KiCad symbol, template and footprint libraries are stored on your computer then click "Save"
5. If you intend to use InvenTree with this tool, click on "Settings > InvenTree" and fill in your InvenTree server address and credentials then click "Save" (optional: click on "Test" to get an API token)
5. If you intend to use InvenTree with this tool, click on "Settings > InvenTree" and fill in your InvenTree server address and credentials then click "Save" (optional: click on "Test" to check communication with server)
i. It is possible to define a Proxy Server over which all interactions with InvenTree will be routed. To set a proxy server use the "Enable Proxy Support" switch in "Settings > InvenTree" and define the proxy address in the new input field.
ii. Instead of user credential authentication token authentication is also supported. To use a token add it it to the "Password or Token" field and leave the "Username" empty. You can retrieve your personal access token from your InvenTree server by sending an get-request to its api url `api/user/token/`.


#### Get Digi-Key API token
<details>
Expand Down
32 changes: 29 additions & 3 deletions kintree/config/config_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,25 @@ def load_inventree_user_settings(user_config_path: str) -> dict:
except TypeError:
user_settings['PASSWORD'] = ''

if 'ENABLE_PROXY' not in user_settings:
user_settings['ENABLE_PROXY'] = False
proxies = user_settings.get('PROXIES', None)
if not proxies:
user_settings['PROXY'] = ''
else:
# loading the proxy independent if it is http or https
user_settings['PROXY'] = list(proxies.values())[0]

return user_settings


def save_inventree_user_settings(enable: bool, server: str, username: str, password: str, user_config_path: str):
def save_inventree_user_settings(enable: bool,
server: str,
username: str,
password: str,
enable_proxy: bool,
proxies: dict,
user_config_path: str):
''' Save InvenTree user settings to file '''
user_settings = {}

Expand All @@ -110,6 +125,8 @@ def save_inventree_user_settings(enable: bool, server: str, username: str, passw
user_settings['USERNAME'] = username
# Use base64 encoding to make password unreadable inside the file
user_settings['PASSWORD'] = base64.b64encode(password.encode())
user_settings['ENABLE_PROXY'] = enable_proxy
user_settings['PROXIES'] = proxies

return dump_file(user_settings, user_config_path)

Expand Down Expand Up @@ -403,12 +420,21 @@ def add_supplier_category(categories: dict, supplier_config_path: str) -> bool:
return dump_file(supplier_categories, supplier_config_path)


def load_category_parameters(category: str, supplier_config_path: str) -> dict:
def load_category_parameters(categories: list, supplier_config_path: str) -> dict:
''' Load Supplier parameters mapping from Supplier settings file '''
try:
category_parameters = load_file(supplier_config_path)[category]
category_file = load_file(supplier_config_path)
except:
return None
category_parameters = None
for category in reversed(categories):
try:
category_parameters = category_file[category]
break
except:
pass
if not category_parameters:
return None

category_parameters_inversed = {}
for parameter in category_parameters.keys():
Expand Down
4 changes: 4 additions & 0 deletions kintree/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,17 @@ def load_inventree_settings():
global SERVER_ADDRESS
global USERNAME
global PASSWORD
global ENABLE_PROXY
global PROXIES
global PART_URL_ROOT

inventree_settings = config_interface.load_inventree_user_settings(INVENTREE_CONFIG)

SERVER_ADDRESS = inventree_settings.get('SERVER_ADDRESS', None)
USERNAME = inventree_settings.get('USERNAME', None)
PASSWORD = inventree_settings.get('PASSWORD', None)
ENABLE_PROXY = inventree_settings.get('ENABLE_PROXY', False)
PROXIES = inventree_settings.get('PROXIES', None)
# Part URL
if SERVER_ADDRESS:
# If missing, append slash to root URL
Expand Down
14 changes: 12 additions & 2 deletions kintree/database/inventree_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,24 @@
from inventree.part import Part, PartCategory, Parameter, ParameterTemplate


def connect(server: str, username: str, password: str, connect_timeout=5, silent=False) -> bool:
def connect(server: str,
username: str,
password: str,
connect_timeout=5,
silent=False,
proxies=None,
token='') -> bool:
''' Connect to InvenTree server and create API object '''
from wrapt_timeout_decorator import timeout
global inventree_api

@timeout(dec_timeout=connect_timeout)
def get_inventree_api_timeout():
return InvenTreeAPI(server, username=username, password=password)
return InvenTreeAPI(server,
username=username,
password=password,
proxies=proxies,
token=token)

try:
inventree_api = get_inventree_api_timeout()
Expand Down
10 changes: 8 additions & 2 deletions kintree/database/inventree_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ def connect_to_server(timeout=5) -> bool:
''' Connect to InvenTree server using user settings '''
connect = False
settings.load_inventree_settings()
if not settings.USERNAME:
token = settings.PASSWORD
else:
token = ''

try:
connect = inventree_api.connect(server=settings.SERVER_ADDRESS,
username=settings.USERNAME,
password=settings.PASSWORD,
proxies=settings.PROXIES,
token=token,
connect_timeout=timeout)
except TimeoutError:
pass
Expand Down Expand Up @@ -141,7 +147,7 @@ def get_categories_from_supplier_data(part_info: dict, supplier_only=False) -> l
if not categories[1] and function_filter:
cprint(f'[INFO]\tSubcategory is filtered using "{filter_parameter}" parameter', silent=settings.SILENT, end='')
# Load parameter map
parameter_map = config_interface.load_category_parameters(categories[0], settings.CONFIG_SUPPLIER_PARAMETERS)
parameter_map = config_interface.load_category_parameters(categories, settings.CONFIG_SUPPLIER_PARAMETERS)
# Build compare list
compare = []
for supplier_parameter, inventree_parameter in parameter_map.items():
Expand Down Expand Up @@ -261,7 +267,7 @@ def translate_form_to_inventree(part_info: dict, category_tree: list, is_custom=
# Load parameters map
if category_tree:
parameter_map = config_interface.load_category_parameters(
category=category_tree[0],
categories=category_tree,
supplier_config_path=settings.CONFIG_SUPPLIER_PARAMETERS,
)
else:
Expand Down
37 changes: 33 additions & 4 deletions kintree/gui/views/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,21 @@
ft.TextField(),
False, # Browse disabled
],
'Password': [
'Password or Token': [
'PASSWORD',
ft.TextField(),
False, # Browse disabled
],
'Enable Proxy Support': [
'ENABLE_PROXY',
SwitchWithRefs(),
False, # Browse disabled
],
'Proxy': [
'PROXY',
ft.TextField(),
False, # Browse disabled
],
'Default Part Revision': [
'INVENTREE_DEFAULT_REV',
ft.TextField(),
Expand Down Expand Up @@ -391,7 +401,10 @@ def update_field(self, name, field, column):
field,
)
elif type(field) == ft.Switch or type(field) == SwitchWithRefs:
field.on_change = lambda _: self.save()
if 'proxy' in name.lower():
field.on_change = lambda _: None
else:
field.on_change = lambda _: self.save()
field.label = name
column.controls.append(
field,
Expand Down Expand Up @@ -732,13 +745,24 @@ class InvenTreeSettingsView(SettingsView):
]

def save(self, file=None, dialog=True):
address = SETTINGS[self.title]['Server Address'][1].value
proxy = SETTINGS[self.title]['Proxy'][1].value
enable_proxy = SETTINGS[self.title]['Enable Proxy Support'][1].value
if not enable_proxy:
proxies = None
elif address.startswith('https'):
proxies = {'https': proxy}
else:
proxies = {'http': proxy}
if file is None:
# Save to InvenTree file
config_interface.save_inventree_user_settings(
enable=global_settings.ENABLE_INVENTREE,
server=SETTINGS[self.title]['Server Address'][1].value,
server=address,
username=SETTINGS[self.title]['Username'][1].value,
password=SETTINGS[self.title]['Password'][1].value,
password=SETTINGS[self.title]['Password or Token'][1].value,
enable_proxy=enable_proxy,
proxies=proxies,
user_config_path=self.settings_file[0]
)
# Alert user
Expand Down Expand Up @@ -816,6 +840,11 @@ def build_column(self):
)
)

# Link Proxy Switch to the input field
ref = ft.Ref[ft.TextField]()
ref.current = SETTINGS[self.title]['Proxy'][1]
SETTINGS[self.title]['Enable Proxy Support'][1].refs = [ref]

# Create IPN fields
ipn_fields_ref = ft.Ref[ft.Row]()
ipn_fields_col = ft.Column(
Expand Down
2 changes: 2 additions & 0 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,8 @@ def check_result(status: str, new_part: bool) -> bool:
server='http://127.0.0.1:8000',
username='admin',
password='admin',
enable_proxy=False,
proxies={},
user_config_path=settings.INVENTREE_CONFIG):
method_success = False

Expand Down

0 comments on commit 8e0ae07

Please sign in to comment.