Exemplo n.º 1
0
class PyPartsOctopart(PyPartsBase):
    '''
    Implementation of the part browse engine
    '''
    def __init__(self, apikey, verbose=False):
        '''
        instanciate an engine
        '''
        self._e = Octopart(apikey=apikey, verbose=verbose)

    def part_search(self, part_query):
        '''
        handles the part lookup/search for the given part query

        part_query: part string to search as product name

        outputs result on stdout
        '''
        limit = 100
        results = self._e.parts_search(q=part_query,
                                       limit=limit)
        start = 0
        hits = results[0]['hits']
        if hits == 0:
            print("No result")
            return ReturnValues.NO_RESULTS

        print("Searched for: '{}'".format(results[0]['request']['q']))
        def show_result(r):
            print(' → {:30} {:30} {}'.format(
                r['item']['mpn'], r['item']['manufacturer']['name'], r['snippet']
            ))

        for r in results[1]:
            show_result(r)
        while hits - limit > limit:
            start += limit
            hits -= limit
            results = self._e.parts_search(q=part_query, limit=limit,
                                            start=start)
            for r in results[1]:
                show_result(r)
        if hits-limit > 0:
            start += limit
            hits -= limit
            results = self._e.parts_search(q=part_query,
                                            limit=hits,
                                            start=start)
            for r in results[1]:
                show_result(r)
        return ReturnValues.OK

    def part_specs(self, part):
        '''
        returns the specifications of the given part. If multiple parts are
        matched, only the first one will be output.

        part: the productname or sku

        prints the results on stdout
        '''
        result = self._e.parts_match(
            queries=[{'mpn_or_sku': part}],
            exact_only=True,
            show_mpn=True,
            show_manufacturer=True,
            show_octopart_url=True,
            show_short_description=True,
            show_specs=True,
            show_category_uids=True,
            show_external_links=True,
            show_reference_designs=True,
            show_cad_models=True,
            show_datasheets=True,
            include_specs=True,
            include_category_uids=True,
            include_external_links=True,
            include_reference_designs=True,
            include_cad_models=True,
            include_datasheets=True
        )
        if result[1][0]['hits'] == 0:
            print("No result")
            return ReturnValues.NO_RESULTS

        result = result[1][0]['items'][0]
        print("Showing specs for '{}':".format(result['mpn']))
        print(" → Manufacturer:      {}".format(result['manufacturer']['name']))
        print("  → Specifications:    ")
        for k,v in result['specs'].items():
            name = v['metadata']['name'] if v['metadata']['name'] else k
            min_value = v['min_value'] if v['min_value'] else ''
            max_value = v['max_value'] if v['max_value'] else ''
            unit = ' ({})'.format(v['metadata']['unit']['name']) if v['metadata']['unit'] else ''
            value = ','.join(v['value']) if len(v['value']) > 0 else ''

            if value and not (min_value or max_value):
                print("    → {:20}: {}{}".format(name, value, unit))
            elif value and min_value and max_value:
                print("    → {:20}: {}{} (min: {}, max: {})".format(name, value, unit, min_value, max_value))
            elif not value and min_value and max_value:
                print("    → {:20}:{} min: {}, max: {}".format(name, unit, min_value, max_value))
            elif not value and min_value and not max_value:
                print("    → {:20}:{} min: {}".format(name, unit, min_value))
            elif not value and not min_value and max_value:
                print("    → {:20}:{} max: {}".format(name, unit, max_value))

        print(" → URI:               {}".format(result['octopart_url']))
        if result['external_links']['evalkit_url'] \
                or result['external_links']['freesample_url'] \
                or result['external_links']['product_url']:
            print("  → External Links")
            if result['external_links']['evalkit_url']:
                print("    → Evaluation kit: {}".format(result['external_links']['evalkit_url']))
            if result['external_links']['freesample_url']:
                print("    → Free Sample: {}".format(result['external_links']['freesample_url']))
            if result['external_links']['product_url']:
                print("    → Product URI: {}".format(result['external_links']['product_url']))
        if len(result['datasheets']) > 0:
            print("  → Datasheets")
            for datasheet in result['datasheets']:
                print("    → URL:      {}".format(datasheet['url']))
                if datasheet['metadata']:
                    print("      → Updated:  {}".format(datasheet['metadata']['last_updated']))
                    print("      → Nb Pages: {}".format(datasheet['metadata']['num_pages']))
        if len(result['reference_designs']) > 0:
            print("  → Reference designs: ")
        if len(result['cad_models']) > 0:
            print("  → CAD Models:        ")
        return ReturnValues.OK

    def part_datasheet(self, part, command=None, path=None):
        '''
        downloads and/or shows the datasheet of a given part

        command: if set will use it to open the datasheet.
        path: if set will download the file under that path.

        if path is given alone, the file will only get downloaded,
        if command is given alone, the file will be downloaded in a temporary
        folder, which will be destroyed just after being opened.
        if both path and command are given, the file will be downloaded and
        stored in the chosen location.
        '''
        result = self._e.parts_match(
            queries=[{'mpn_or_sku': part}],
            exact_only=True,
            show_mpn=True,
            show_datasheets=True,
            include_datasheets=True
        )
        if result[1][0]['hits'] == 0:
            print("No result")
            return ReturnValues.NO_RESULTS

        result = result[1][0]['items'][0]
        print("Downloading datasheet for '{}':".format(result['mpn']))
        try:
            if len(result['datasheets']) > 0:
                for datasheet in result['datasheets']:
                    if not path:
                        path = tempfile.mkdtemp()
                    out = path+'/'+result['mpn']+'-'+datasheet['url'].split('/')[-1]
                    download_file(datasheet['url'], out)
                    print('Datasheet file saved as {}.'.format(out))
                    if command:
                        subprocess.call([command, out])
        finally:
            if not path:
                shutil.rmtree(path)
        return ReturnValues.OK

    def part_show(self, part, printout=False):
        '''
        Opens/shows the aggregator's URI for the part.


        printout: if set, only printout the URI, do not open the browser.
        '''

        result = self._e.parts_match(
            queries=[{'mpn_or_sku': part}],
            exact_only=True,
            show_mpn=True,
            show_octopart_url=True
        )
        if result[1][0]['hits'] == 0:
            print("No result")
            return ReturnValues.NO_RESULTS
        result = result[1][0]['items'][0]
        if not printout:
            print("Opening page for part '{}'.".format(result['mpn']))
            webbrowser.open(result['octopart_url'], 2)
        else:
            print("Webpage for part '{}':".format(result['mpn']))
            print("    → URL:      {}".format(result['octopart_url']))
        return ReturnValues.OK