def _load_guidelines(self): with open(self._guidelinefile, 'r') as f: data = yaml.load(f) self._idents = data['idents'] self._generators = data['generators'] self._devices = data['devices'] self._default = data['default']
def get_configs_file(self): with open(self._cfpath) as configfile: configdata = yaml.load(configfile) try: return self._verify_schema_decl(configdata) except SchemaNotSupportedError as e: self._validation_errors.add(e)
def create(self, title=None, desc=None, cards=None, deltas=None, sourcing_order_snos=None, root_order_snos=None, ordered_by=None, order_yaml_path=None, snomap_path=None, force=False): # Load in the various parameters and such, creating the necessary # containers only. self._force = force if self._defined is True and self._force is False: raise Exception("This production order instance seems to be " "already defined. You can't 'create' it again.") if order_yaml_path is not None: self._order_yaml_path = order_yaml_path with open(self._order_yaml_path, 'r') as f: self._yaml_data = yaml.load(f) self._load_order_yaml_data() if title: self._title = title if desc: self._desc = desc if cards: self._cards = cards if deltas: self._deltas = deltas if sourcing_order_snos: self._sourcing_order_snos = sourcing_order_snos if root_order_snos: self._root_order_snos = root_order_snos if ordered_by: self._ordered_by = ordered_by if snomap_path: self._snomap_path = snomap_path if len(self._cards) + len(self._deltas) == 0: raise NothingToProduceError
def get_pcbpricing_data(projfolder): pcbpricingfp = os.path.join(projfolder, 'pcb', 'sourcing.yaml') if not os.path.exists(pcbpricingfp): return None with open(pcbpricingfp, 'r') as f: data = yaml.load(f) return data
def _load_descriptors(self): gpf = projfile.GedaProjectFile(self._projectfolder) pricingfp = os.path.join(gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml') if not os.path.exists(pricingfp): logger.debug( "PCB does not have sourcing file. Not loading prices : " + self._pcbname ) return None with open(pricingfp, 'r') as f: data = yaml.load(f) self._descriptors.append(str(data['params']['dX']) + 'mm x ' + str(data['params']['dY']) + 'mm') # noqa if data["params"]["layers"] == 2: self._descriptors.append("Double Layer") elif data["params"]["layers"] == 4: self._descriptors.append("ML4") # HAL, Sn, Au, PBFREE, H, NP, I, OC if data["params"]["finish"] == 'Au': self._descriptors.append("Immersion Gold/ENIG finish") elif data["params"]["finish"] == 'Sn': self._descriptors.append("Immersion Tin finish") elif data["params"]["finish"] == 'PBFREE': self._descriptors.append("Any Lead Free finish") elif data["params"]["finish"] == 'H': self._descriptors.append("Lead F ree HAL finish") elif data["params"]["finish"] == 'NP': self._descriptors.append("No Copper finish") elif data["params"]["finish"] == 'I': self._descriptors.append("OSP finish") elif data["params"]["finish"] == 'OC': self._descriptors.append("Only Copper finish") else: self._descriptors.append("UNKNOWN FINISH: " + data["params"]["finish"]) # noqa self._descriptors.append("10 Working Days")
def _load_snomap_legacy(self): # New form should construct directly from DB snomap_path = docstore.get_docs_list_for_sno_doctype( serialno=self._sno, doctype='SNO MAP', one=True).path with docstore.docstore_fs.open(snomap_path, 'r') as f: snomap_data = yaml.load(f) self._snomap = SerialNumberMap(snomap_data, self._sno)
def create(self, title=None, desc=None, cards=None, deltas=None, sourcing_order_snos=None, root_order_snos=None, ordered_by=None, order_yaml_path=None, snomap_path=None, force=False): # Load in the various parameters and such, creating the necessary # containers only. self._force = force if self._defined is True and self._force is False: raise Exception("This production order instance seems to be already " "done. You can't 'create' it again.") if order_yaml_path is not None: self._order_yaml_path = order_yaml_path with open(self._order_yaml_path, 'r') as f: self._yaml_data = yaml.load(f) self._load_order_yaml_data() if title: self._title = title if desc: self._desc = desc if cards: self._cards = cards if deltas: self._deltas = deltas if sourcing_order_snos: self._sourcing_order_snos = sourcing_order_snos if root_order_snos: self._root_order_snos = root_order_snos if ordered_by: self._ordered_by = ordered_by if snomap_path: self._snomap_path = snomap_path if len(self._cards) + len(self._deltas) == 0: raise NothingToProduceError
def _load_snomap_legacy(self): # New form should construct directly from DB snomap_path = docstore.get_docs_list_for_sno_doctype( serialno=self._sno, doctype='SNO MAP', one=True ).path with docstore.docstore_fs.open(snomap_path, 'r') as f: snomap_data = yaml.load(f) self._snomap = SerialNumberMap(snomap_data, self._sno)
def _load_order_yaml(self): try: order_path = docstore.get_docs_list_for_sno_doctype( serialno=self._sno, doctype='PRODUCTION ORDER YAML', one=True ).path except SerialNoNotFound: raise ProductionOrderNotFound with docstore.docstore_fs.open(order_path, 'r') as f: self._yaml_data = yaml.load(f)
def _load_external_sources(self): external_configs = yml.load(self._path) for config in external_configs: try: if config['format'] == 'json': self._sources.append( ConfigExternalJSONSource(config['path'], config['keymap'])) else: raise ExternalConfigFormatError(config['path'], config['filetype']) except ExternalConfigMissingError: pass
def __init__(self, vendor, inv_yaml, working_folder=None): vendor_defaults_file = os.path.join(CUSTOMSDEFAULTS_FOLDER, vendor._name + '.yaml') self._data = {} if os.path.exists(vendor_defaults_file): with open(vendor_defaults_file, 'r') as f: vendor_defaults = yaml.load(f) self._data = vendor_defaults.copy() else: logger.warning("Vendor Customs Defaults File Not Found : " + vendor_defaults_file) self._source_folder = os.path.split(inv_yaml)[0] if working_folder is None: self._working_folder = self._source_folder else: self._working_folder = working_folder with open(inv_yaml, 'r') as f: inv_data = yaml.load(f) self._data.update(inv_data) self._linetype = CustomsInvoiceLine vendor.currency = currency.CurrencyDefinition( vendor.currency.code, vendor.currency.symbol, exchval=self._data['exchrate'] ) super(CustomsInvoice, self).__init__( vendor, self._data['invoice_no'], self._data['invoice_date'] ) self.freight = 0 self.insurance_pc = 0 self._includes_freight = False self._added_insurance = False self._process_other_costs() hs_codes_file = os.path.join(CUSTOMSDEFAULTS_FOLDER, 'hs_codes.yaml') with open(hs_codes_file, 'r') as f: self._hs_codes = yaml.load(f) self._sections = []
def __init__(self, vendor, inv_yaml, working_folder=None): vendor_defaults_file = os.path.join(CUSTOMSDEFAULTS_FOLDER, vendor._name + '.yaml') self._data = {} if os.path.exists(vendor_defaults_file): with open(vendor_defaults_file, 'r') as f: vendor_defaults = yaml.load(f) self._data = vendor_defaults.copy() else: logger.warning("Vendor Customs Defaults File Not Found : " + vendor_defaults_file) self._source_folder = os.path.split(inv_yaml)[0] if working_folder is None: self._working_folder = self._source_folder else: self._working_folder = working_folder with open(inv_yaml, 'r') as f: inv_data = yaml.load(f) self._data.update(inv_data) self._linetype = CustomsInvoiceLine vendor.currency = currency.CurrencyDefinition( vendor.currency.code, vendor.currency.symbol, exchval=self._data['exchrate']) super(CustomsInvoice, self).__init__(vendor, self._data['invoice_no'], self._data['invoice_date']) self.freight = 0 self.insurance_pc = 0 self._includes_freight = False self._added_insurance = False self._process_other_costs() hs_codes_file = os.path.join(CUSTOMSDEFAULTS_FOLDER, 'hs_codes.yaml') with open(hs_codes_file, 'r') as f: self._hs_codes = yaml.load(f) self._sections = []
def __init__(self, name, dname, pclass, mappath=None, currency_code=None, currency_symbol=None, pricelistpath=None, **kwargs): if pricelistpath is None: pricelistpath = os.path.join(PRICELISTVENDORS_FOLDER, name + '-pricelist.yaml') with open(pricelistpath, 'r') as f: self._pricelist = yaml.load(f) self._last_updated = get_file_mtime(pricelistpath) if currency_code is None: currency_code = self._pricelist["currency"]["code"].strip() if currency_symbol is None: currency_symbol = self._pricelist["currency"]["symbol"].strip() self._currency = currency.CurrencyDefinition( currency_code, currency_symbol ) super(VendorPricelist, self).__init__(name, dname, pclass, mappath, currency_code, currency_symbol, **kwargs) if 'vendorinfo' in self._pricelist: if "effectivefactor" in self._pricelist["vendorinfo"]: self.add_order_additional_cost_component( "Unspecified", self._pricelist["vendorinfo"]["effectivefactor"] * 100 ) self._vpart_class = PricelistPart try: self.add_order_baseprice_component( "Shipping Cost", self._pricelist["vendorinfo"]["shippingcost"] ) except KeyError: pass if "prices" not in self._pricelist: try: pass except: logger.error("No prices found for " + self.name) if "pricegens" in self._pricelist: self._generate_insert_idents() if "pricecsv" in self._pricelist: self._load_pricecsv(self._pricelist["pricecsv"])
def _load_prices(self): gpf = projfile.GedaProjectFile(self._projectfolder) pricingfp = os.path.join(gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml') if not os.path.exists(pricingfp): logger.debug( "PCB does not have sourcing file. Not loading prices : " + self._pcbname) return None with open(pricingfp, 'r') as f: data = yaml.load(f) for qty, prices in viewitems(data['pricing']): if 10 not in prices.keys(): logger.warning( "Default Delivery Time not in prices. Quantity pricing not imported : " + # noqa str([qty, self._pcbname])) else: price = VendorPrice(qty, prices[10], self._vendor.currency) self._prices.append(price)
def _load_product_info(self): with open(self._fpath, 'r') as f: self._raw_data = yaml.load(f) self._name = self._raw_data['name'] self._card_names = self._raw_data['cards'] self._cable_names = self._raw_data['cables'] self._labels = self._raw_data['labels'] # TODO Some products don't have a viable core. Allowances must be made # Eg QM anf QI. self._core = self._raw_data['derive_sno_from'] self._calibformat = self._raw_data['calibformat'] try: self._product_info = \ INSTANCE_PRODUCT_CLASSES.get_product_info_class( self._raw_data['productinfo']['line'], infodict=self._raw_data['productinfo'], parent=self ) except ImportError: self._product_info = ProductInfo( infodict=self._raw_data['productinfo'], parent=self)
def __init__(self, name, dname, pclass, mappath=None, currency_code=None, currency_symbol=None, pricelistpath=None, **kwargs): if pricelistpath is None: pricelistpath = os.path.join(PRICELISTVENDORS_FOLDER, name + '-pricelist.yaml') with open(pricelistpath, 'r') as f: self._pricelist = yaml.load(f) self._last_updated = get_file_mtime(pricelistpath) if currency_code is None: currency_code = self._pricelist["currency"]["code"].strip() if currency_symbol is None: currency_symbol = self._pricelist["currency"]["symbol"].strip() self._currency = currency.CurrencyDefinition(currency_code, currency_symbol) super(VendorPricelist, self).__init__(name, dname, pclass, mappath, currency_code, currency_symbol, **kwargs) if 'vendorinfo' in self._pricelist: if "effectivefactor" in self._pricelist["vendorinfo"]: self.add_order_additional_cost_component( "Unspecified", self._pricelist["vendorinfo"]["effectivefactor"] * 100) self._vpart_class = PricelistPart try: self.add_order_baseprice_component( "Shipping Cost", self._pricelist["vendorinfo"]["shippingcost"]) except KeyError: pass if "prices" not in self._pricelist: logger.error("No prices found for " + self.name) if "pricegens" in self._pricelist: self._generate_insert_idents() if "pricecsv" in self._pricelist: self._load_pricecsv(self._pricelist["pricecsv"])
def get_customs_invoice(serialno): documents = docstore.controller.get_sno_documents(serialno=serialno) inv_yaml = None for document in documents: if document.doctype == 'INVOICE-DATA-YAML': inv_yaml = document.docpath if not inv_yaml: raise ValueError('Invoice data not found for : ' + serialno) with docstore.docstore_fs.open(inv_yaml, 'r') as f: inv_data = yaml.load(f) inv_format = inv_data['invoice_format'] if inv_format == 'analogdevices': from tendril.sourcing import pricelist invoice_class = pricelist.AnalogDevicesInvoice elif inv_format == 'digikey': from tendril.sourcing.vendors import digikey invoice_class = digikey.DigiKeyInvoice else: raise ValueError('Unrecognized Customs Invoice Format : ' + inv_format) from tendril.sourcing import electronics vobj = electronics.get_vendor_by_name(inv_format) workspace_name = get_tempname() docstore.copy_docs_to_workspace(serialno=serialno, workspace=workspace_name, clearws=True, fs=temp_fs) invoice = invoice_class( vobj, temp_fs.getsyspath( fs.path.join(workspace_name, 'inv_data.yaml') ) ) temp_fs.removedir(workspace_name, recursive=True, force=True) return invoice
def get_customs_invoice(serialno): documents = docstore.controller.get_sno_documents(serialno=serialno) inv_yaml = None for document in documents: if document.doctype == 'INVOICE-DATA-YAML': inv_yaml = document.docpath if not inv_yaml: raise ValueError('Invoice data not found for : ' + serialno) with docstore.docstore_fs.open(inv_yaml, 'r') as f: inv_data = yaml.load(f) inv_format = inv_data['invoice_format'] if inv_format == 'analogdevices': from tendril.sourcing import pricelist invoice_class = pricelist.AnalogDevicesInvoice elif inv_format == 'digikey': from tendril.sourcing import digikey invoice_class = digikey.DigiKeyInvoice else: raise ValueError('Unrecognized Customs Invoice Format : ' + inv_format) from tendril.sourcing import electronics vobj = electronics.get_vendor_by_name(inv_format) workspace_name = get_tempname() docstore.copy_docs_to_workspace(serialno=serialno, workspace=workspace_name, clearws=True, fs=temp_fs) invoice = invoice_class( vobj, temp_fs.getsyspath( fs.path.join(workspace_name, 'inv_data.yaml') ) ) temp_fs.removedir(workspace_name, recursive=True, force=True) return invoice
def _load_product_info(self): with open(self._fpath, 'r') as f: self._raw_data = yaml.load(f) self._name = self._raw_data['name'] self._card_names = self._raw_data['cards'] self._cable_names = self._raw_data['cables'] self._labels = self._raw_data['labels'] # TODO Some products don't have a viable core. Allowances must be made # Eg QM anf QI. self._core = self._raw_data['derive_sno_from'] self._calibformat = self._raw_data['calibformat'] try: self._product_info = \ INSTANCE_PRODUCT_CLASSES.get_product_info_class( self._raw_data['productinfo']['line'], infodict=self._raw_data['productinfo'], parent=self ) except ImportError: self._product_info = ProductInfo( infodict=self._raw_data['productinfo'], parent=self )
def _load_prices(self): gpf = projfile.GedaProjectFile(self._projectfolder) pricingfp = os.path.join(gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml') if not os.path.exists(pricingfp): logger.debug( "PCB does not have sourcing file. Not loading prices : " + self._pcbname ) return None with open(pricingfp, 'r') as f: data = yaml.load(f) for qty, prices in viewitems(data['pricing']): if 10 not in prices.keys(): logger.warning( "Default Delivery Time not in prices. Quantity pricing not imported : " + # noqa str([qty, self._pcbname]) ) else: price = VendorPrice( qty, prices[10], self._vendor.currency ) self._prices.append(price)
def _load_descriptors(self): gpf = projfile.GedaProjectFile(self._projectfolder) pricingfp = os.path.join(gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml') if not os.path.exists(pricingfp): logger.debug( "PCB does not have sourcing file. Not loading prices : " + self._pcbname) return None with open(pricingfp, 'r') as f: data = yaml.load(f) self._descriptors.append( str(data['params']['dX']) + 'mm x ' + str(data['params']['dY']) + 'mm') # noqa if data["params"]["layers"] == 2: self._descriptors.append("Double Layer") elif data["params"]["layers"] == 4: self._descriptors.append("ML4") # HAL, Sn, Au, PBFREE, H, NP, I, OC if data["params"]["finish"] == 'Au': self._descriptors.append("Immersion Gold/ENIG finish") elif data["params"]["finish"] == 'Sn': self._descriptors.append("Immersion Tin finish") elif data["params"]["finish"] == 'PBFREE': self._descriptors.append("Any Lead Free finish") elif data["params"]["finish"] == 'H': self._descriptors.append("Lead F ree HAL finish") elif data["params"]["finish"] == 'NP': self._descriptors.append("No Copper finish") elif data["params"]["finish"] == 'I': self._descriptors.append("OSP finish") elif data["params"]["finish"] == 'OC': self._descriptors.append("Only Copper finish") else: self._descriptors.append("UNKNOWN FINISH: " + data["params"]["finish"]) # noqa self._descriptors.append("10 Working Days")
from tendril.utils.config import INSTANCE_ROOT from tendril.utils.files import yml as yaml from tendril.utils import log logger = log.get_logger(__name__, log.DEFAULT) if __name__ == '__main__': bomlist = [] orderfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'sourcing', 'current') orderfile = os.path.join(orderfolder, 'order.yaml') with open(orderfile, 'r') as f: data = yaml.load(f) LOAD_PRESHORT = False LOAD_EXTERNAL_REQ = False EXTERNAL_REQ_IMMEDIATE = True external_req_file = None USE_STOCK = True IS_INDICATIVE = False indication_context = None PRIORITIZE = False PRELIMINARY = False IMMEDIATE_EARMARKS = [] if 'preshort' in data.keys(): LOAD_PRESHORT = data['preshort'] if 'use_stock' in data.keys():
def _get_yaml_file(self): if self.template and not os.path.exists(self._path): self._generate_stub() if self.FileNotFoundExceptionType and not os.path.exists(self._path): raise self.FileNotFoundExceptionType(self._path) return yaml.load(self._path)
def _load_sections(self): hs_codes_file = os.path.join(CUSTOMSDEFAULTS_FOLDER, 'hs_codes.yaml') with open(hs_codes_file, 'r') as f: data = yaml.load(f) for section, sectiondict in data['sections'].iteritems(): self._sections.append(CustomsSection(section, sectiondict))
def _process(self, outfolder=None, manifestsfolder=None, label_manager=None, register=False, force=False, pb_class=None, stacked_pb=False, leaf_pb=True, session=None): self._force = force if pb_class is None: pb_class = TendrilProgressBar if stacked_pb is True: pb = pb_class(max=8) else: pb = DummyProgressBar(max=8) pb.next(note="Constructing Resources for Production Order Generation") if outfolder is None: if self._order_yaml_path is not None: outfolder = os.path.split(self._order_yaml_path)[0] else: raise AttributeError('Output folder needs to be defined') if manifestsfolder is None: manifestsfolder = os.path.join(outfolder, 'manifests') if not os.path.exists(manifestsfolder): os.makedirs(manifestsfolder) if self._sno is None: self._sno = serialnos.get_serialno( series='PROD', efield=self._title, register=register, session=session ) # Create Snomap if self._snomap_path is not None: with open(self._snomap_path, 'r') as f: self._snomap = SerialNumberMap(yaml.load(f), self._sno) else: self._snomap = SerialNumberMap({}, self._sno) self._snomap.set_session(session=session) if register is True: self._snomap.enable_creation() indent_sno = self._snomap.get_sno('indentsno') if register is True: serialnos.link_serialno(child=indent_sno, parent=self.serialno, verbose=False, session=session) # Create cards and deltas and so forth pb.next(note="Constructing Production Order Actions") actions = self.card_actions + self.delta_actions pb.next(note="Executing Production Order Actions") for action in actions: if register is False: action.scaffold = True action.set_session(session=session) action.commit( outfolder=manifestsfolder, indent_sno=indent_sno, prod_ord_sno=self._sno, register=register, session=session, pb_class=pb_class, stacked_pb=stacked_pb, leaf_pb=leaf_pb, ) self._snomap.disable_creation() pb.next(note="Constructing Composite Output BOM") cobom = CompositeOutputBom(self.bomlist) pb.next(note="Creating Indent(s)") self._process_indents( indent_sno=indent_sno, cobom=cobom, outfolder=outfolder, register=register, force=force, session=session ) pb.next(note="Generating Production Order Document") # Make production order doc self._last_generated_at = arrow.utcnow().isoformat() if self._first_generated_at is None: self._first_generated_at = arrow.utcnow().isoformat() self._dump_order_yaml(outfolder=outfolder, register=register, session=session) self._generate_doc(outfolder=outfolder, register=register, session=session) pb.next(note="Generating Labels") self.make_labels(label_manager=label_manager, pb_class=pb_class, stacked_pb=stacked_pb, leaf_pb=leaf_pb) pb.next(note="Finalizing Production Order") for action in actions: action.scaffold = False action.unset_session() self._snomap.dump_to_file(outfolder) self._snomap.unset_session() if register is True: docstore.register_document( serialno=self.serialno, docpath=os.path.join(outfolder, 'snomap.yaml'), doctype='SNO MAP', efield=self.title, verbose=False, session=session ) pb.finish() self._defined = True
def _get_data(self): with open(self._genpath) as genfile: gendata = yaml.load(genfile) if gendata["schema"]["name"] == "gsymgenerator" and gendata["schema"]["version"] == 1.0: if gendata["type"] == "simple": self._type = "Simple" self._ivalues = [v for v in gendata["values"] if v is not None and v.strip() is not None] return gendata["values"] values = [] if gendata["type"] == "resistor": self._type = "Resistor" for resistance in gendata["resistances"]: if resistance is not None: values.append(resistance) self._iunits.append(resistance) if "generators" in gendata.keys(): for generator in gendata["generators"]: self._igen.append(generator) if generator["std"] == "iec60063": rvalues = iec60063.gen_vals( generator["series"], iec60063.res_ostrs, start=generator["start"], end=generator["end"] ) for rvalue in rvalues: values.append(construct_resistor(rvalue, generator["wattage"])) # noqa else: raise ValueError if "values" in gendata.keys(): if gendata["values"][0].strip() != "": values += gendata["values"] self._ivalues.extend(gendata["values"]) if "custom_series" in gendata.keys(): from tendril.conventions.series import CustomValueSeries for name, series in viewitems(gendata["custom_series"]): if series["detail"].pop("type") != "resistor": raise ValueError("Expected a resistor series") vals = series["values"] tsymbol = GedaSymbol(self._sympath) iseries = CustomValueSeries( name, "resistor", device=tsymbol.device, footprint=tsymbol.footprint ) for type_val, val in viewitems(vals): iseries.add_value(type_val, val) iseries._desc = series["detail"].pop("desc") iseries._aparams = series["detail"] self._iseries.append(iseries) values.extend(vals.values()) return values if gendata["type"] == "capacitor": self._type = "Capacitor" for capacitance in gendata["capacitances"]: if capacitance is not None: values.append(capacitance) self._iunits.append(capacitance) if "generators" in gendata.keys(): for generator in gendata["generators"]: self._igen.append(generator) if generator["std"] == "iec60063": cvalues = iec60063.gen_vals( generator["series"], iec60063.cap_ostrs, start=generator["start"], end=generator["end"] ) for cvalue in cvalues: values.append(construct_capacitor(cvalue, generator["voltage"])) # noqa else: raise ValueError if "values" in gendata.keys(): if gendata["values"][0].strip() != "": values += gendata["values"] self._ivalues.append(gendata["values"]) if "custom_series" in gendata.keys(): from tendril.conventions.series import CustomValueSeries for name, series in viewitems(gendata["custom_series"]): if series["detail"].pop("type") != "resistor": raise ValueError("Expected a resistor series") vals = series["values"] tsymbol = GedaSymbol(self._sympath) iseries = CustomValueSeries( name, "resistor", device=tsymbol.device, footprint=tsymbol.footprint ) for type_val, val in viewitems(vals): iseries.add_value(type_val, val) iseries._desc = series["detail"].pop("desc") iseries._aparams = series["detail"] self._iseries.append(iseries) values.extend(vals.values()) return values elif gendata["type"] == "wire": for gauge in gendata["gauges"]: for color in gendata["colors"]: values.append("{0} {1}".format(gauge, color)) return values else: logger.ERROR("Config file schema is not supported")
def get_configs_file(self): configdata = yaml.load(self._cfpath) try: return self._verify_schema_decl(configdata) except SchemaNotSupportedError as e: self._validation_errors.add(e)
def gen_pcbpricing(projfolder, namebase, force=False): """ Generates a PDF file with the pricing of the (bare) PCB provided by the gEDA project. The pcb file is the one listed in the gEDA project file, and the pcbname is the one specified in the :mod:`tendril.gedaif.conffile.ConfigsFile`. The pricing information is read out from the PCB's ``sourcing.yaml`` file, which in turn is intended to be created by sourcing modules. .. todo:: This function presently uses :func:`tendril.dox.render.render_lineplot`, which is marked for deprecation. It should be rewritten to use the :func:`tendril.dox.render.make_graph` route instead. :param projfolder: The gEDA project folder. :type projfolder: str :param namebase: The project name. :type namebase: str :param force: Regenerate even if up-to-date. :type force: bool :return: The output file path. .. rubric:: Paths * Output File : ``<project_doc_folder>/<namebase>-pricing.pdf`` * Source Files : ``<projectfolder>/pcb/sourcing.yaml`` """ gpf = projfile.GedaProjectFile(projfolder) pcbpricingfp = os.path.join(gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml') pcbpricing_mtime = fsutils.get_file_mtime(pcbpricingfp) if not os.path.exists(pcbpricingfp): return None docfolder = get_project_doc_folder(projfolder) plotfile = path.join(docfolder, namebase + '-pricing.pdf') outf_mtime = fsutils.get_file_mtime(plotfile, fs=refdoc_fs) if not force and outf_mtime is not None and outf_mtime > pcbpricing_mtime: logger.debug('Skipping up-to-date ' + pcbpricingfp) return pcbpricingfp logger.info('Regnerating ' + plotfile + os.linesep + 'Last modified : ' + str(pcbpricing_mtime) + '; Last Created : ' + str(outf_mtime)) with open(pcbpricingfp, 'r') as f: data = yaml.load(f) workspace_outpath = workspace_fs.getsyspath(plotfile) workspace_folder = workspace_fs.getsyspath(path.dirname(plotfile)) workspace_fs.makedir(path.dirname(plotfile), recursive=True, allow_recreate=True) plot1file = os.path.join(workspace_folder, namebase + '-1pricing.pdf') plot2file = os.path.join(workspace_folder, namebase + '-2pricing.pdf') pltnote = "This pricing refers to the bare PCB only. " \ "See the corresponding Config Docs for Card Pricing" plt1data = { key: data['pricing'][key] for key in data['pricing'].keys() if key <= 10 } plt1title = gpf.configsfile.configdata['pcbname'] plt1title += " PCB Unit Price vs Order Quantity (Low Quantity)" plot1file = render.render_lineplot(plot1file, plt1data, plt1title, pltnote) if max(data['pricing'].keys()) > 10: plt2data = { key: data['pricing'][key] for key in data['pricing'].keys() if key > 10 } plt2title = gpf.configsfile.configdata['pcbname'] plt2title += " PCB Unit Price vs Order Quantity (Production Quantity)" plot2file = render.render_lineplot(plot2file, plt2data, plt2title, pltnote) pdf.merge_pdf([plot1file, plot2file], workspace_outpath) os.remove(plot2file) else: shutil.copyfile(plot1file, workspace_outpath) os.remove(plot1file) copyfile(workspace_fs, plotfile, refdoc_fs, plotfile, overwrite=True) return plotfile
def _get_data(self): with open(self._genpath) as genfile: gendata = yaml.load(genfile) if gendata["schema"]["name"] == "gsymgenerator" and \ gendata["schema"]["version"] == 1.0: if gendata['type'] == 'simple': self._type = 'Simple' self._ivalues = [ v for v in gendata['values'] if v is not None and v.strip() is not None ] return gendata['values'] values = [] if gendata['type'] == 'resistor': self._type = 'Resistor' giseries = None for resistance in gendata['resistances']: if resistance is not None: values.append(resistance) self._iunits.append(resistance) if 'composite_series' in gendata.keys(): from tendril.conventions.series import CustomValueSeries try: name = gendata['composite_series']['name'] tsymbol = GedaSymbol(self._sympath) giseries = CustomValueSeries( name, 'resistor', device=tsymbol.device, footprint=tsymbol.footprint) except KeyError: pass if 'generators' in gendata.keys(): dcomponents = jb_resistor_defs() for generator in gendata['generators']: self._igen.append(generator) if generator['std'] == 'iec60063': rvalues = iec60063.gen_vals( generator['series'], iec60063.res_ostrs, start=generator['start'], end=generator['end']) components = {} for dcomponent in dcomponents: if dcomponent.code in generator.keys(): try: dcomponent.typeclass( generator[dcomponent.code]) # noqa components[ dcomponent.code] = generator[ dcomponent.code] # noqa except: raise ValueError for rvalue in rvalues: pval = construct_resistor(resistance=rvalue, **components) values.append(pval) if giseries is not None: giseries.add_value(rvalue, pval) else: raise ValueError if giseries is not None: self._iseries.append(giseries) if 'values' in gendata.keys(): if gendata['values'][0].strip() != '': values += gendata['values'] self._ivalues.extend(gendata['values']) if 'custom_series' in gendata.keys(): from tendril.conventions.series import CustomValueSeries for name, series in viewitems(gendata['custom_series']): if series['detail'].pop('type') != 'resistor': raise ValueError('Expected a resistor series') vals = series['values'] tsymbol = GedaSymbol(self._sympath) iseries = CustomValueSeries( name, 'resistor', device=tsymbol.device, footprint=tsymbol.footprint) for type_val, val in viewitems(vals): iseries.add_value(type_val, val) iseries._desc = series['detail'].pop('desc') iseries._aparams = series['detail'] self._iseries.append(iseries) values.extend(vals.values()) return values if gendata['type'] == 'capacitor': self._type = 'Capacitor' giseries = None for capacitance in gendata['capacitances']: if capacitance is not None: values.append(capacitance) self._iunits.append(capacitance) if 'composite_series' in gendata.keys(): from tendril.conventions.series import CustomValueSeries try: name = gendata['composite_series']['name'] tsymbol = GedaSymbol(self._sympath) giseries = CustomValueSeries( name, 'capacitor', device=tsymbol.device, footprint=tsymbol.footprint) except KeyError: pass if 'generators' in gendata.keys(): dcomponents = jb_capacitor_defs() for generator in gendata['generators']: self._igen.append(generator) if generator['std'] == 'iec60063': cvalues = iec60063.gen_vals( generator['series'], iec60063.cap_ostrs, start=generator['start'], end=generator['end']) components = {} for dcomponent in dcomponents: if dcomponent.code in generator.keys(): try: dcomponent.typeclass( generator[dcomponent.code]) # noqa components[ dcomponent.code] = generator[ dcomponent.code] # noqa except: raise ValueError for cvalue in cvalues: pval = construct_capacitor(capacitance=cvalue, **components) values.append(pval) if giseries is not None: giseries.add_value(cvalue, pval) else: raise ValueError if giseries is not None: self._iseries.append(giseries) if 'values' in gendata.keys(): if gendata['values'][0].strip() != '': values += gendata['values'] self._ivalues.append(gendata['values']) if 'custom_series' in gendata.keys(): from tendril.conventions.series import CustomValueSeries for name, series in viewitems(gendata['custom_series']): if series['detail'].pop('type') != 'capacitor': raise ValueError('Expected a capacitor series') vals = series['values'] tsymbol = GedaSymbol(self._sympath) iseries = CustomValueSeries( name, 'capacitor', device=tsymbol.device, footprint=tsymbol.footprint) for type_val, val in viewitems(vals): iseries.add_value(type_val, val) iseries._desc = series['detail'].pop('desc') iseries._aparams = series['detail'] self._iseries.append(iseries) values.extend(vals.values()) return values elif gendata['type'] == 'wire': for gauge in gendata['gauges']: for color in gendata['colors']: values.append('{0} {1}'.format(gauge, color)) return values else: logger.ERROR("Config file schema is not supported")
def gen_pcbpricing(projfolder, namebase, force=False): """ Generates a PDF file with the pricing of the (bare) PCB provided by the gEDA project. The pcb file is the one listed in the gEDA project file, and the pcbname is the one specified in the :mod:`tendril.gedaif.conffile.ConfigsFile`. The pricing information is read out from the PCB's ``sourcing.yaml`` file, which in turn is intended to be created by sourcing modules. .. todo:: This function presently uses :func:`tendril.dox.render.render_lineplot`, which is marked for deprecation. It should be rewritten to use the :func:`tendril.dox.render.make_graph` route instead. :param projfolder: The gEDA project folder. :type projfolder: str :param namebase: The project name. :type namebase: str :param force: Regenerate even if up-to-date. :type force: bool :return: The output file path. .. rubric:: Paths * Output File : ``<project_doc_folder>/<namebase>-pricing.pdf`` * Source Files : ``<projectfolder>/pcb/sourcing.yaml`` """ gpf = projfile.GedaProjectFile(projfolder) pcbpricingfp = os.path.join( gpf.configsfile.projectfolder, 'pcb', 'sourcing.yaml' ) pcbpricing_mtime = fsutils.get_file_mtime(pcbpricingfp) if not os.path.exists(pcbpricingfp): return None docfolder = get_project_doc_folder(projfolder) plotfile = path.join(docfolder, namebase + '-pricing.pdf') outf_mtime = fsutils.get_file_mtime(plotfile, fs=refdoc_fs) if not force and outf_mtime is not None and outf_mtime > pcbpricing_mtime: logger.debug('Skipping up-to-date ' + pcbpricingfp) return pcbpricingfp logger.info('Regnerating ' + plotfile + os.linesep + 'Last modified : ' + str(pcbpricing_mtime) + '; Last Created : ' + str(outf_mtime)) with open(pcbpricingfp, 'r') as f: data = yaml.load(f) workspace_outpath = workspace_fs.getsyspath(plotfile) workspace_folder = workspace_fs.getsyspath(path.dirname(plotfile)) workspace_fs.makedir(path.dirname(plotfile), recursive=True, allow_recreate=True) plot1file = os.path.join(workspace_folder, namebase + '-1pricing.pdf') plot2file = os.path.join(workspace_folder, namebase + '-2pricing.pdf') pltnote = "This pricing refers to the bare PCB only. " \ "See the corresponding Config Docs for Card Pricing" plt1data = {key: data['pricing'][key] for key in data['pricing'].keys() if key <= 10} plt1title = gpf.configsfile.configdata['pcbname'] plt1title += " PCB Unit Price vs Order Quantity (Low Quantity)" plot1file = render.render_lineplot( plot1file, plt1data, plt1title, pltnote ) if max(data['pricing'].keys()) > 10: plt2data = {key: data['pricing'][key] for key in data['pricing'].keys() if key > 10} plt2title = gpf.configsfile.configdata['pcbname'] plt2title += " PCB Unit Price vs Order Quantity (Production Quantity)" plot2file = render.render_lineplot( plot2file, plt2data, plt2title, pltnote ) pdf.merge_pdf([plot1file, plot2file], workspace_outpath) os.remove(plot2file) else: shutil.copyfile(plot1file, workspace_outpath) os.remove(plot1file) copyfile(workspace_fs, plotfile, refdoc_fs, plotfile, overwrite=True) return plotfile
def _process(self, outfolder=None, manifestsfolder=None, label_manager=None, register=False, force=False, pb_class=None, stacked_pb=False, leaf_pb=True, session=None): self._force = force if pb_class is None: pb_class = TendrilProgressBar if stacked_pb is True: pb = pb_class(max=8) else: pb = DummyProgressBar(max=8) pb.next(note="Constructing Resources for Production Order Generation") if outfolder is None: if self._order_yaml_path is not None: outfolder = os.path.split(self._order_yaml_path)[0] else: raise AttributeError('Output folder needs to be defined') if manifestsfolder is None: manifestsfolder = os.path.join(outfolder, 'manifests') if not os.path.exists(manifestsfolder): os.makedirs(manifestsfolder) if self._sno is None: self._sno = serialnos.get_serialno( series='PROD', efield=self._title, register=register, session=session ) # Create Snomap if self._snomap_path is not None: with open(self._snomap_path, 'r') as f: self._snomap = SerialNumberMap(yaml.load(f), self._sno) else: self._snomap = SerialNumberMap({}, self._sno) self._snomap.set_session(session=session) if register is True: self._snomap.enable_creation() indent_sno = self._snomap.get_sno('indentsno') if register is True: serialnos.link_serialno(child=indent_sno, parent=self.serialno, verbose=False, session=session) # Create cards and deltas and so forth pb.next(note="Constructing Production Order Actions") actions = self.card_actions + self.delta_actions pb.next(note="Executing Production Order Actions") for action in actions: if register is False: action.scaffold = True action.set_session(session=session) action.commit( outfolder=manifestsfolder, indent_sno=indent_sno, prod_ord_sno=self._sno, register=register, session=session, pb_class=pb_class, stacked_pb=stacked_pb, leaf_pb=leaf_pb, ) self._snomap.disable_creation() pb.next(note="Constructing Composite Output BOM") cobom = CompositeOutputBom(self.bomlist) # Assume Indent is non-empty. # Create indent pb.next(note="Creating Indent") indent = InventoryIndent(indent_sno, verbose=False, session=session) indent.create(cobom, title="FOR {0}".format(self.serialno), desc=None, indent_type='production', requested_by=self._ordered_by, force=force) indent.define_auth_chain(prod_order_sno=self.serialno, session=session, prod_order_scaffold=True) indent.process(outfolder=outfolder, register=register, verbose=False, session=session) self._indents.append(indent) pb.next(note="Generating Production Order Document") # Make production order doc self._last_generated_at = arrow.utcnow().isoformat() if self._first_generated_at is None: self._first_generated_at = arrow.utcnow().isoformat() self._dump_order_yaml(outfolder=outfolder, register=register, session=session) self._generate_doc(outfolder=outfolder, register=register, session=session) pb.next(note="Generating Labels") self.make_labels(label_manager=label_manager, pb_class=pb_class, stacked_pb=stacked_pb, leaf_pb=leaf_pb) pb.next(note="Finalizing Production Order") for action in actions: action.scaffold = False action.unset_session() self._snomap.dump_to_file(outfolder) self._snomap.unset_session() if register is True: docstore.register_document( serialno=self.serialno, docpath=os.path.join(outfolder, 'snomap.yaml'), doctype='SNO MAP', efield=self.title, verbose=False, session=session ) pb.finish() self._defined = True