Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Extract each information, by the the header given, for each
# row part, spliting it in a list.
value = extract_field(row, hdr.lower())
value = re.split(ALTIUM_PART_SEPRTR, value)
if hdr.lower() in ign_fields:
continue
elif not SEPRTR in hdr.lower():
for i in range(qty):
if len(value)==qty:
v = value[i]
else:
v = value[0] # Footprint is just one for group.
# Do not create empty fields. This is useful
# when used more than one `manf#` alias in one designator.
if v and v!=ALTIUM_NONE:
fields[i][field_name_translations.get(hdr.lower(),hdr.lower())] = v.strip()
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.{})?:(?P.*)'.format(variant)
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
# The field name is anything that came after the leading
# 'kicost' and variant field.
name = mtch.group('name')
name = field_name_translations.get(name, name)
# If the field name isn't for a manufacturer's part
# number or a distributors catalog number, then add
# it to 'local' if it doesn't start with a distributor
# name and colon.
if name not in ('manf#', 'manf') and name[:-1] not in distributor_dict:
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.(?P.*))?:(?P.*)'
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
v = mtch.group('variant')
if v is not None and not re.match(variant, v, flags=re.IGNORECASE):
continue
if v is not None:
logger.log(DEBUG_OBSESSIVE, 'Matched Variant ... ' + v + mtch.group('name') )
# The field name is anything that came after the leading
# 'kicost' and optional variant field.
name = mtch.group('name')
name = field_name_translations.get(name, name)
# If the field name isn't for a manufacturer's part
# number or a distributors catalog number, then add
# it to 'local' if it doesn't start with a distributor
# name and colon.
#if name not in ('manf#', 'manf', 'desc', 'value', 'comment', 'S1PN', 'S1MN', 'S1PL', 'S2PN', 'S2MN', 'S2PL') and name[:-1] not in distributor_dict:
dist_mtch = re.match('([^:]+):',name)
if dist_mtch and dist_mtch.group(1) not in distributor_dict:
# 'name' is a distibutore (preceded & followed with ':'
logger.log(DEBUG_OBSESSIVE, 'Assigning local: for name "{}" dist "{}" ... '.format(name,dist_mtch.group(1)) )
# Original code supposes that name is a distributor
if SEPRTR not in name: # This field has no distributor.
name = 'local:' + name # Assign it to a local distributor.
value = str(f.string)
if value or v is not None:
# Empty value also propagated to force deleting default value
fields[name] = value
def extract_fields(part, variant):
# Extract XML fields from the part in a library or schematic.
fields = {}
try:
for f in part.find('fields').find_all('field'):
# Store the name and value for each kicost-related field.
# Remove case of field name along with leading/trailing whitespace.
name = str(f['name']).lower().strip()
if name in ign_fields:
continue # Ignore fields in the ignore list.
elif SEPRTR not in name: # No separator, so get global field value.
name = field_name_translations.get(name, name)
value = str(f.string)
if value and name not in fields:
# Only set the field if it is not set yet (which indicates a variant
# has been parsed before)
fields[name] = value # Do not create empty fields. This is useful
# when used more than one `manf#` alias in one designator.
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.(?P.*))?:(?P.*)'
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
v = mtch.group('variant')
if v is not None and not re.match(variant, v, flags=re.IGNORECASE):
continue
name = field_name_translations.get(name, name)
value = str(f.string)
if value:
fields[name] = value # Do not create empty fields. This is usefull
# when used more than one `manf#` alias in one designator.
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.{})?:(?P.*)'.format(variant)
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
# The field name is anything that came after the leading
# 'kicost' and variant field.
name = mtch.group('name')
name = field_name_translations.get(name, name)
# If the field name isn't for a manufacturer's part
# number or a distributors catalog number, then add
# it to 'local' if it doesn't start with a distributor
# name and colon.
if name not in ('manf#', 'manf') and name[:-1] not in distributor_dict:
if SEPRTR not in name: # This field has no distributor.
name = 'local:' + name # Assign it to a local distributor.
value = str(f.string)
if value:
fields[name] = value
except AttributeError:
pass # No fields found for this part.
return fields
def extract_fields(part, variant):
# Extract XML fields from the part in a library or schematic.
fields = {}
try:
for f in part.find('fields').find_all('field'):
# Store the name and value for each kicost-related field.
# Remove case of field name along with leading/trailing whitespace.
name = str(f['name']).lower().strip()
if name in ign_fields:
continue # Ignore fields in the ignore list.
elif SEPRTR not in name: # No separator, so get global field value.
name = field_name_translations.get(name, name)
value = str(f.string)
if value:
fields[name] = value # Do not create empty fields. This is usefull
# when used more than one `manf#` alias in one designator.
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.{})?:(?P.*)'.format(variant)
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
# The field name is anything that came after the leading
# 'kicost' and variant field.
name = mtch.group('name')
name = field_name_translations.get(name, name)
# If the field name isn't for a manufacturer's part
dialect = csv.Sniffer().sniff(content, [',',';','\t'])
except csv.Error:
# If the CSV file only has a single column of data, there may be no
# delimiter so just set the delimiter to a comma.
dialect = csv.Sniffer().sniff(',,,', [','])
# The first line in the file must be the column header.
content = content.splitlines()
logger.log(DEBUG_OVERVIEW, 'Getting CSV header...')
header_file = next(csv.reader(content,delimiter=dialect.delimiter))
if len(set(header_file))
'''
# Add or remove field translations, ignore in case the trying to
# re-translate default field names.
if translate_fields:
if len(translate_fields)%2 == 1:
raise Exception('Translation fields argument should have an even number of words.')
for c in range(0, len(translate_fields), 2):
#field_name_translations.keys(), field_name_translations.values()
if translate_fields[c] in field_name_translations.values():
logger.warning("Not possible re-translate \"{}\" to \"{}\", this is used as internal field names.".format(
translate_fields[c].lower(), translate_fields[c+1].lower()
))
continue
if translate_fields[c+1]!='~':
field_name_translations.update({translate_fields[c].lower():translate_fields[c+1].lower()})
else:
field_name_translations.pop(translate_fields[c].lower(), None)
# Check the integrity of the user personal fields, this should not
# be any of the reserved fields.
# This is checked after the translation `dict` is complete, so an
# before used name field on the translate dictionary can be used
# user field.
user_fields = list(set(user_fields))
for f in user_fields:
if f.lower() in field_name_translations.keys():
logger.warning("\"{f}\" field is a reserved field and can not be used user filed. Try to remove it from internal dictionary using `--translate_filed {f} ~`".format(
f=f.lower()
))
user_fields.remove(x)
# Libraries.
import sys, os, time
if sys.version_info < (3,0):
import copy # Necessary because Py2 doesn't have copy in list.
from datetime import datetime
from bs4 import BeautifulSoup # To Read XML files.
import re # Regular expression parser.
import logging
from ..global_vars import logger, DEBUG_OVERVIEW, DEBUG_DETAILED, DEBUG_OBSESSIVE # Debug configurations.
from ..global_vars import SEPRTR
from ..distributors.global_vars import distributor_dict
from .tools import field_name_translations, remove_dnp_parts
from .tools import PART_REF_REGEX_NOT_ALLOWED
# Add to deal with the fileds of Altium and WEB tools.
field_name_translations.update(
{
'designator': 'refs',
'quantity': 'qty',
'manufacturer name': 'manf', # Used for some web site tools to part generator in Altium.
'manufacturer part number': 'manf#'
}
)
ALTIUM_NONE = '[NoParam]' # Value of Altium to `None`.
ALTIUM_PART_SEPRTR = r'(?
from datetime import datetime
import csv # CSV file reader.
import re # Regular expression parser.
import logging
from ..global_vars import logger, DEBUG_OVERVIEW, DEBUG_DETAILED, DEBUG_OBSESSIVE # Debug configurations.
from .tools import field_name_translations, remove_dnp_parts, split_refs
from ..distributors.global_vars import distributor_dict
from .eda import eda_class
class generic_csv(eda_class):
def __init__(self):
pass
# Add to deal with the generic CSV header purchase list.
field_name_translations.update(
{
'stock code': 'manf#',
'mfr. no': 'manf#',
'manpartno': 'manf#',
'quantity': 'qty',
'order qty': 'qty',
'references': 'refs',
'reference': 'refs',
'ref': 'refs',
'customer no': 'refs',
'parts': 'refs',
'part': 'refs',
'value': 'value',
'package': 'footprint',
'pcb package': 'footprint', # Used at Proteus.
'': '', # This is here because the header row may contain an empty field.
# If the field name isn't for a manufacturer's part
# number or a distributors catalog number, then add
# it to 'local' if it doesn't start with a distributor
# name and colon.
if name not in ('manf#', 'manf') and name[:-1] not in distributor_dict:
if SEPRTR not in name: # This field has no distributor.
name = 'local:' + name # Assign it to a local distributor.
for i in range(qty):
if len(value)==qty:
v = value[i]
else:
v = value[0] # Footprint is just one for group.
# Do not create empty fields. This is useful
# when used more than one `manf#` alias in one designator.
if v and v!=ALTIUM_NONE:
fields[i][field_name_translations.get(hdr.lower(),hdr.lower())] = v.strip()
return refs, fields