Exemplo n.º 1
0
def copy_docs_to_workspace(serialno=None,
                           workspace=None,
                           clearws=False,
                           setwsno=True,
                           fs=None,
                           session=None):
    if serialno is None:
        raise AttributeError('serialno cannot be None')
    if fs is None:
        fs = workspace_fs
    if workspace is None:
        workspace = fs.makeopendir('workspace', recursive=True)
    elif workspace.startswith('/'):
        raise ValueError('workspace should be a relative path')
    else:
        workspace = fs.makeopendir(workspace, recursive=True)
    if clearws is True:
        for p in workspace.listdir(dirs_only=True):
            workspace.removedir(p, force=True)
        for p in workspace.listdir(files_only=True):
            workspace.remove(p)
    if setwsno is True:
        with workspace.open('wsno', 'wb') as f:
            f.write(serialno)
    for doc in controller.get_sno_documents(serialno=serialno,
                                            session=session):
        docname = os.path.split(doc.docpath)[1]
        if docname.startswith(serialno):
            if not os.path.splitext(docname)[0] == serialno:
                docname = docname[len(serialno) + 1:]
        copyfile(docstore_fs, doc.docpath, workspace, docname)
Exemplo n.º 2
0
 def _copy_files(self, src, dst, path, src_i, dst_i, files, truncated= False, depth= 0, cached_status= None,verbose=True):
     if verbose and files: print "\t"*depth+"Copy files"
     status= cached_status
     for file, info in files:
         if verbose: print "\t"*depth+"Object: "+file
         if not cached_status or cached_status==PathStatus.ignore or not self.cache_file_status:
             status= self.config.GetPathStatus(path+[file])
         if status==PathStatus.include:
             src_index= None
             dst_index= None
             src_mtime= info["modified_time"]
             src_filesize= info["size"]
             
             try:
                 copyfile(src, file, dst, file)
                 #Change mod of newly created file
                 #to mod of a source file
                 dst.chmod(file, get_fmod(info))
             except:
                 continue
             if src_filesize>=0:
                 print "Sync synch synch..............................."
                 src_index= src_i.GetPathPart([src_i.name,file], True)
                 dst_index= dst_i.GetPathPart([dst_i.name,file], True)
                 src_index.CreationTime= self.dt2ut(src_mtime)
                 dst_index.CreationTime= self.dt2ut(dst.getinfo(file)["modified_time"])   
         if status==PathStatus.stop:
             if verbose: print "\t"*depth+"Removing file"
             src.remove(file)    
Exemplo n.º 3
0
def copy_docs_to_workspace(serialno=None, workspace=None, clearws=False, setwsno=True, fs=None, session=None):
    if serialno is None:
        raise AttributeError("serialno cannot be None")
    if fs is None:
        fs = workspace_fs
    if workspace is None:
        workspace = fs.makeopendir("workspace", recursive=True)
    elif workspace.startswith("/"):
        raise ValueError("workspace should be a relative path")
    else:
        workspace = fs.makeopendir(workspace, recursive=True)
    if clearws is True:
        for p in workspace.listdir(dirs_only=True):
            workspace.removedir(p, force=True)
        for p in workspace.listdir(files_only=True):
            workspace.remove(p)
    if setwsno is True:
        with workspace.open("wsno", "wb") as f:
            f.write(serialno)
    for doc in controller.get_sno_documents(serialno=serialno, session=session):
        docname = os.path.split(doc.docpath)[1]
        if docname.startswith(serialno):
            if not os.path.splitext(docname)[0] == serialno:
                docname = docname[len(serialno) + 1 :]
        copyfile(docstore_fs, doc.docpath, workspace, docname)
Exemplo n.º 4
0
def copy_file(source_fs,
              source_path,
              target_fs,
              target_path,
              overwrite=True,
              create_directory=True,
              chunk_size=64 * 1024):
    """
    Copy a file from one filesystem/path to another filesystem/path.
    This will create the target directory if necessary,
    unless create_directory is set to False.

    """

    try:
        utils.copyfile(source_fs,
                       source_path,
                       target_fs,
                       target_path,
                       overwrite=overwrite,
                       chunk_size=chunk_size)
    except ParentDirectoryMissingError:
        if create_directory:
            target_fs.makedir(os.path.dirname(target_path),
                              recursive=True,
                              allow_recreate=True)
            utils.copyfile(source_fs,
                           source_path,
                           target_fs,
                           target_path,
                           overwrite=overwrite,
                           chunk_size=chunk_size)
        else:
            raise
Exemplo n.º 5
0
def gen_pcb_dxf(projfolder, force=False):
    """
    Generates a DXF file of the 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`.

    This function does not use jinja2 and latex. It relies on
    :func:`tendril.connectors.geda.pcb.conv_pcb2dxf` instead.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output File :  ``<projectfolder>/pcb/<pcbfile>.dxf``
    * Source Files : The project's `.pcb` file.

    """
    configfile = conffile.ConfigsFile(projfolder)
    gpf = projfile.GedaProjectFile(configfile.projectfolder)
    pcb_mtime = fsutils.get_file_mtime(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
    )
    if pcb_mtime is None:
        logger.warning("PCB does not seem to exist for : " + projfolder)
        return
    docfolder = get_project_doc_folder(projfolder)
    dxffile = path.normpath(os.path.join(docfolder, os.pardir,
                            configfile.pcbname + '.dxf'))
    bottom_dxffile = path.normpath(os.path.join(docfolder, os.pardir,
                                   configfile.pcbname + 'bottom.dxf'))

    outf_mtime = fsutils.get_file_mtime(dxffile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > pcb_mtime:
        logger.debug('Skipping up-to-date ' + dxffile)
        return dxffile

    logger.info('Regenerating ' + dxffile + os.linesep +
                'Last modified : ' + str(pcb_mtime) +
                '; Last Created : ' + str(outf_mtime))

    workspace_folder = workspace_fs.getsyspath(path.dirname(dxffile))
    workspace_fs.makedir(path.dirname(dxffile),
                         recursive=True, allow_recreate=True)

    pcb.conv_pcb2dxf(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
        workspace_folder, configfile.pcbname
    )

    copyfile(workspace_fs, dxffile, refdoc_fs, dxffile, overwrite=True)
    copyfile(workspace_fs, bottom_dxffile, refdoc_fs, bottom_dxffile, overwrite=True)
    return dxffile
Exemplo n.º 6
0
def gen_pcb_dxf(projfolder, force=False):
    """
    Generates a DXF file of the 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`.

    This function does not use jinja2 and latex. It relies on
    :func:`tendril.gedaif.pcb.conv_pcb2dxf` instead.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output File :  ``<projectfolder>/pcb/<pcbfile>.dxf``
    * Source Files : The project's `.pcb` file.

    """
    configfile = conffile.ConfigsFile(projfolder)
    gpf = projfile.GedaProjectFile(configfile.projectfolder)
    pcb_mtime = fsutils.get_file_mtime(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
    )
    if pcb_mtime is None:
        logger.warning("PCB does not seem to exist for : " + projfolder)
        return
    docfolder = get_project_doc_folder(projfolder)
    dxffile = path.normpath(os.path.join(docfolder, os.pardir,
                            configfile.pcbname + '.dxf'))
    bottom_dxffile = path.normpath(os.path.join(docfolder, os.pardir,
                                   configfile.pcbname + 'bottom.dxf'))

    outf_mtime = fsutils.get_file_mtime(dxffile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > pcb_mtime:
        logger.debug('Skipping up-to-date ' + dxffile)
        return dxffile

    logger.info('Regenerating ' + dxffile + os.linesep +
                'Last modified : ' + str(pcb_mtime) +
                '; Last Created : ' + str(outf_mtime))

    workspace_folder = workspace_fs.getsyspath(path.dirname(dxffile))
    workspace_fs.makedir(path.dirname(dxffile),
                         recursive=True, allow_recreate=True)

    pcb.conv_pcb2dxf(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
        workspace_folder, configfile.pcbname
    )

    copyfile(workspace_fs, dxffile, refdoc_fs, dxffile, overwrite=True)
    copyfile(workspace_fs, bottom_dxffile, refdoc_fs, bottom_dxffile, overwrite=True)
    return dxffile
Exemplo n.º 7
0
    def patchfile(self, path):
        """Patch remote file with new user file if size has changed"""
        user_info = self.userfs.getinfo(path)
        remote_info = self.remotefs.getinfo(path)

        if user_info["size"] != remote_info["size"]:
            copyfile(self.userfs, path, self.remotefs, path, overwrite=True)
            print(term.yellow + " " * 4 + "updated " + path + term.normal)
Exemplo n.º 8
0
    def patchfile(self, path):
        """Patch remote file with new user file if size has changed"""
        user_info = self.userfs.getinfo(path)
        remote_info = self.remotefs.getinfo(path)

        if user_info["size"] != remote_info["size"]:
            copyfile(self.userfs, path, self.remotefs, path, overwrite=True)
            print(term.yellow + " " * 4 + "updated " + path + term.normal)
    def copy(self, dst, **kwargs):
        """Copy file to a new destination.

        Returns JSON Patch with proposed change pointing to new copy.
        """
        _fs, filename = opener.parse(self.uri)
        _fs_dst, filename_dst = opener.parse(dst)
        copyfile(_fs, filename, _fs_dst, filename_dst, **kwargs)
        return [{'op': 'replace', 'path': self.pointer, 'value': dst}]
Exemplo n.º 10
0
    def copy(self, dst, **kwargs):
        """Copy file to a new destination.

        Returns JSON Patch with proposed change pointing to new copy.
        """
        _fs, filename = opener.parse(self.uri)
        _fs_dst, filename_dst = opener.parse(dst)
        copyfile(_fs, filename, _fs_dst, filename_dst, **kwargs)
        return [{'op': 'replace', 'path': self.pointer, 'value': dst}]
Exemplo n.º 11
0
Arquivo: start.py Projeto: esaye/moya
def copy_new(src, dst):
    """Copy files from src fs to dst fst only if they don't exist on dst"""
    from fs.utils import copystructure, copyfile
    copystructure(src, dst)
    copied_files = []
    for path in src.walkfiles():
        if not dst.exists(path):
            copyfile(src, path, dst, path)
            copied_files.append(path)
    return copied_files
Exemplo n.º 12
0
def copy_new(src, dst):
    """Copy files from src fs to dst fst only if they don't exist on dst"""
    from fs.utils import copystructure, copyfile
    copystructure(src, dst)
    copied_files = []
    for path in src.walkfiles():
        if not dst.exists(path):
            copyfile(src, path, dst, path)
            copied_files.append(path)
    return copied_files
Exemplo n.º 13
0
def insert_document(sno, docpath, series):
    fname = os.path.split(docpath)[1]
    if not fname.startswith(sno) and not os.path.splitext(fname)[0].endswith(sno):
        fname = sno + "-" + fname
    if series is None:
        series = serialnos.get_series(sno)
    storepath = path.join(series, fname)
    if not docstore_fs.exists(path.dirname(storepath)):
        docstore_fs.makedir(path.dirname(storepath), recursive=True)
    copyfile(local_fs, docpath, docstore_fs, storepath)
    return storepath
Exemplo n.º 14
0
    def sync_files(self):
        """Copy files that don't exist on remote fs or patch them if they do exist"""
        if self.mode != "update":
            raise NotImplementedError("Only the update mode has been implemented yet.")

        for path in self.userfs.walkfiles():
            if self.remotefs.exists(path):
                self.patchfile(path)
            else:
                copyfile(self.userfs, path, self.remotefs, path, overwrite=False)
                print(term.green + " " * 4 + "copied " + path + term.normal)
Exemplo n.º 15
0
def get_sendable_path(fspath, fs, fs_root):
    if isinstance(fs, OSFS):
        path = os.path.join(fs_root, fspath)
    else:
        path = temp_expose_fs.getsyspath(fspath)
        if not temp_expose_fs.exists(fspath):
            temp_expose_fs.makedir(os.path.split(fspath)[0],
                                   recursive=True,
                                   allow_recreate=True)
            copyfile(fs, fspath, temp_expose_fs, fspath)
    return path
Exemplo n.º 16
0
def gen_schpdf(projfolder, namebase, force=False):
    """
    Generates a PDF file of all the project schematics listed in the
    gEDA project file. This function does not ise jinja2 and latex. It
    relies on :func:`tendril.gedaif.gschem.conv_gsch2pdf` 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>-schematic.pdf``
    * Source Files : The project's schematic folder.

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    configfile = conffile.ConfigsFile(projfolder)
    docfolder = get_project_doc_folder(projfolder)

    schpdfpath = path.join(docfolder, namebase + '-schematic.pdf')
    outf_mtime = fsutils.get_file_mtime(schpdfpath, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + schpdfpath)
        return schpdfpath

    logger.info('Regenerating ' + schpdfpath + os.linesep +
                'Last modified : ' + str(sch_mtime) +
                '; Last Created : ' + str(outf_mtime))

    if configfile.rawconfig is not None:
        workspace_outpath = workspace_fs.getsyspath(schpdfpath)
        workspace_folder = workspace_fs.getsyspath(path.dirname(schpdfpath))
        workspace_fs.makedir(path.dirname(schpdfpath),
                             recursive=True, allow_recreate=True)
        pdffiles = []
        for schematic in gpf.schfiles:
            schfile = os.path.normpath(projfolder + '/schematic/' + schematic)
            pdffile = gschem.conv_gsch2pdf(schfile, workspace_folder)
            pdffiles.append(pdffile)
        pdf.merge_pdf(pdffiles, workspace_outpath)
        for pdffile in pdffiles:
            os.remove(pdffile)
        copyfile(workspace_fs, schpdfpath,
                 refdoc_fs, schpdfpath,
                 overwrite=True)
        return schpdfpath
Exemplo n.º 17
0
def insert_document(sno, docpath, series):
    fname = os.path.split(docpath)[1]
    if not fname.startswith(sno) and \
            not os.path.splitext(fname)[0].endswith(sno):
        fname = sno + '-' + fname
    if series is None:
        series = serialnos.get_series(sno)
    storepath = path.join(series, fname)
    if not docstore_fs.exists(path.dirname(storepath)):
        docstore_fs.makedir(path.dirname(storepath), recursive=True)
    copyfile(local_fs, docpath, docstore_fs, storepath)
    return storepath
Exemplo n.º 18
0
def copy_file(source_fs, source_path, target_fs, target_path, overwrite=True, create_directory=True, chunk_size=64 * 1024):
    """
    Copy a file from one filesystem/path to another filesystem/path.
    This will create the target directory if necessary,
    unless create_directory is set to False.

    """

    try:
        utils.copyfile(source_fs, source_path, target_fs, target_path, overwrite=overwrite, chunk_size=chunk_size)
    except ParentDirectoryMissingError:
        if create_directory:
            target_fs.makedir(os.path.dirname(target_path), recursive=True, allow_recreate=True)
            utils.copyfile(source_fs, source_path, target_fs, target_path, overwrite=overwrite, chunk_size=chunk_size)
        else:
            raise
Exemplo n.º 19
0
    def sync_files(self):
        """Copy files that don't exist on remote fs or patch them if they do exist"""
        if self.mode != "update":
            raise NotImplementedError(
                "Only the update mode has been implemented yet.")

        for path in self.userfs.walkfiles():
            if self.remotefs.exists(path):
                self.patchfile(path)
            else:
                copyfile(self.userfs,
                         path,
                         self.remotefs,
                         path,
                         overwrite=False)
                print(term.green + " " * 4 + "copied " + path + term.normal)
Exemplo n.º 20
0
def get_sendable_path(fspath, fs, fs_root):
    if isinstance(fs, OSFS):
        path = os.path.join(fs_root, fspath)
    else:
        path = temp_expose_fs.getsyspath(fspath)
        if not temp_expose_fs.exists(fspath):
            temp_expose_fs.makedir(
                os.path.split(fspath)[0],
                recursive=True,
                allow_recreate=True
            )
            copyfile(
                fs, fspath,
                temp_expose_fs, fspath
            )
    return path
Exemplo n.º 21
0
def get_production_order_manifest_set(serialno):
    workspace = temp_fs.makeopendir(get_tempname())
    children = serialnos.get_child_serialnos(sno=serialno)
    manifests = []
    for child in children:
        files = []

        am = docstore.get_docs_list_for_sno_doctype(serialno=child,
                                                    doctype='ASSEMBLY MANIFEST')
        if len(am) == 1:
            uam = am[0]
            copyfile(uam.fs, uam.path, workspace, uam.filename, overwrite=True)
            files = [workspace.getsyspath(uam.filename)]
        elif len(am) > 1:
            raise ValueError(
                    "Found {0} manifests for {2}".format(len(am), child)
            )

        dms = docstore.get_docs_list_for_sno_doctype(
                serialno=child, doctype='DELTA ASSEMBLY MANIFEST'
        )
        if len(dms):
            for dm in dms:
                copyfile(dm.fs, dm.path, workspace, dm.filename,
                         overwrite=True)
                files.append(workspace.getsyspath(dm.filename))

        if len(files) > 1:
            wdmfile = merge_pdf(
                files,
                os.path.join(workspace.getsyspath('/'),
                             os.path.splitext(am[0].filename)[0] + '-wdm.pdf'),
                remove_sources=True
            )
            manifests.append(wdmfile)
        elif len(files) == 1:
            manifests.append(files[0])

    if len(manifests):
        output = merge_pdf(
            manifests,
            os.path.join(workspace.getsyspath('/'), serialno + '.pdf'),
            remove_sources=True
        )
        return output
    return None
Exemplo n.º 22
0
def get_production_order_manifest_set(serialno):
    workspace = temp_fs.makeopendir(get_tempname())
    children = serialnos.get_child_serialnos(sno=serialno)
    manifests = []
    for child in children:
        files = []

        am = docstore.get_docs_list_for_sno_doctype(
            serialno=child, doctype='ASSEMBLY MANIFEST')
        if len(am) == 1:
            uam = am[0]
            copyfile(uam.fs, uam.path, workspace, uam.filename, overwrite=True)
            files = [workspace.getsyspath(uam.filename)]
        elif len(am) > 1:
            raise ValueError("Found {0} manifests for {2}".format(
                len(am), child))

        dms = docstore.get_docs_list_for_sno_doctype(
            serialno=child, doctype='DELTA ASSEMBLY MANIFEST')
        if len(dms):
            for dm in dms:
                copyfile(dm.fs,
                         dm.path,
                         workspace,
                         dm.filename,
                         overwrite=True)
                files.append(workspace.getsyspath(dm.filename))

        if len(files) > 1:
            wdmfile = merge_pdf(
                files,
                os.path.join(workspace.getsyspath('/'),
                             os.path.splitext(am[0].filename)[0] + '-wdm.pdf'),
                remove_sources=True)
            manifests.append(wdmfile)
        elif len(files) == 1:
            manifests.append(files[0])

    if len(manifests):
        output = merge_pdf(manifests,
                           os.path.join(workspace.getsyspath('/'),
                                        serialno + '.pdf'),
                           remove_sources=True)
        return output
    return None
Exemplo n.º 23
0
def build(src_fs, dst_fs):
    """Build a firmware"""
    if not src_fs.exists('firmware.conf'):
        src_fs.setcontents('firmware.conf', DEFAULT_FIRMWARE_CONF)

    cfg = SafeConfigParser()
    with src_fs.open('firmware.conf') as f:
        cfg.readfp(f)

    version = int(cfg.get('firmware', 'version'))
    exclude = _get_list(cfg.get('firmware', 'exclude'))

    def wildcard(path):
        return not any(fnmatch(basename(path), wildcard) for wildcard in exclude)

    for file_path in src_fs.walkfiles(wildcard=wildcard, dir_wildcard=wildcard):
        copyfile(src_fs, file_path, dst_fs, file_path)

    return version
Exemplo n.º 24
0
def build(src_fs, dst_fs):
    """Build a firmware"""
    if not src_fs.exists('firmware.conf'):
        src_fs.setcontents('firmware.conf', DEFAULT_FIRMWARE_CONF)

    cfg = SafeConfigParser()
    with src_fs.open('firmware.conf') as f:
        cfg.readfp(f)

    version = int(cfg.get('firmware', 'version'))
    exclude = _get_list(cfg.get('firmware', 'exclude'))

    def wildcard(path):
        return not any(fnmatch(basename(path), wildcard) for wildcard in exclude)

    for file_path in src_fs.walkfiles(wildcard=wildcard, dir_wildcard=wildcard):
        copyfile(src_fs, file_path, dst_fs, file_path)

    return version
Exemplo n.º 25
0
    def _process_files(self, metadata):
        """Transfer files in a list from one ``fs`` object to another.

        All tranferer files will maintain the same filename.
        """
        # FS object created at the folder of where the record specific bag is
        fs_dest = opener.opendir(self.folder, "files", create_dir=True)

        files_to_upload = []
        for file_to_upload in metadata.get("files", []):
            dirname_ = os.path.dirname(file_to_upload["path"])
            basename_ = os.path.basename(file_to_upload["path"])
            fs_src = opener.opendir(dirname_)
            copyfile(fs_src, basename_, fs_dest, basename_)
            file_to_upload["path"] = os.path.join("files", basename_)
            del file_to_upload["url"]
            files_to_upload.append(file_to_upload)
        metadata["files_to_upload"] = files_to_upload
        return metadata
Exemplo n.º 26
0
    def transfer_data_files(self):
        """Transfer files in a list from one ``fs`` object to another.

        All tranferer files will maintain the same filename.
        """
        # FS object created at the folder of where the record specific bag is
        fs_dest = opener.opendir(self.bagit_folder_path, create_dir=True)

        try:

            for docfile in self.docfiles:
                fs_src = opener.opendir(os.path.dirname(docfile.get_path()))
                copyfile(fs_src, os.path.basename(docfile.get_path()),
                         fs_dest, os.path.basename(docfile.get_path()))

        except Exception:
            raise ArchiverError("Error while copying %s to %s"
                                % (docfile.get_path(),
                                    os.path.join(self.bagit_folder_path,
                                                 docfile.name +
                                                 docfile.format)))
        return True
Exemplo n.º 27
0
def get_document_path(key):
    """
    Returns the absolute path to the document in the wallet referred to
    by the ``key``.

    If the wallet fs root is not an OS filesystem, then it copies the
    wallet document into the temporary folder and returns the path to it.

    :param key: Key of the document you want.
    :return: The absolute path to the document.
    """

    if key in DOCUMENT_WALLET.keys():
        try:
            return wallet_fs.getsyspath(DOCUMENT_WALLET[key])
        except NoSysPathError:
            if not wallet_temp_fs.exists(DOCUMENT_WALLET[key]):
                copyfile(wallet_fs, DOCUMENT_WALLET[key],
                         wallet_temp_fs, DOCUMENT_WALLET[key])
            return wallet_temp_fs.getsyspath(DOCUMENT_WALLET[key])
    else:
        raise ValueError
Exemplo n.º 28
0
    def _accessor(self, max_age, getcpath=False, *args, **kwargs):
        """
        The primary accessor for the cache instance. Each subclass should
        provide a function which behaves similarly to that of the original,
        un-cached version of the resource getter. That function should adapt
        the parameters provided to it into the form needed for this one, and
        let this function maintain the cached responses and handle retrieval
        of the response.

        If the module's :data:`_internet_connected` is set to False, the
        cached value is returned regardless.

        """
        filepath = self._get_filepath(*args, **kwargs)
        send_cached = False
        if not _internet_connected and self._cached_exists(filepath):
            send_cached = True
        if self._is_cache_fresh(filepath, max_age):
            logger.debug("Cache HIT")
            send_cached = True
        if send_cached is True:
            if getcpath is False:
                try:
                    filecontent = self.cache_fs.open(filepath, 'rb').read()
                    return self._deserialize(filecontent)
                except UnicodeDecodeError:
                    # TODO This requires the cache_fs to be a local
                    # filesystem. This may not be very nice. A way
                    # to hook codecs upto to pyfilesystems would be better
                    with codecs.open(self.cache_fs.getsyspath(filepath),
                                     encoding='utf-8') as f:
                        filecontent = f.read()
                        return self._deserialize(filecontent)
            else:
                return self.cache_fs.getsyspath(filepath)

        logger.debug("Cache MISS")
        data = self._get_fresh_content(*args, **kwargs)
        try:
            sdata = self._serialize(data)
            fd, temppath = tempfile.mkstemp()
            fp = os.fdopen(fd, 'wb')
            fp.write(sdata)
            fp.close()
            logger.debug("Creating new cache entry")
            # This can be pretty expensive if the move is across a real
            # filesystem boundary. We should instead use a temporary file
            # in the cache_fs itself
            try:
                copyfile(temp_fs, temp_fs.unsyspath(temppath), self.cache_fs,
                         filepath)
                if isinstance(self.cache_fs, OSFS):
                    # TODO Refine permissions
                    os.chmod(self.cache_fs.getsyspath(filepath), 0o666)
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                logger.warning("Unable to write cache file "
                               "{0}".format(filepath))
        except:
            raise

        if getcpath is False:
            return data
        else:
            return self.cache_fs.getsyspath(filepath)
Exemplo n.º 29
0
def gen_confdoc(projfolder, configname, force=False):
    """
    Generate a PDF documenting a single configuration of the project. The
    document should include a reasonably thorough representation of the
    contents of the configuration related sections of the
    `tendril.gedaif.conffile.ConfigsFile``.

    :param projfolder: The gEDA project folder
    :type projfolder: str
    :param configname: The configuration name for which the BOM should be
                       generated.
    :type configname: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output File :  ``<project_doc_folder>/confdocs/<configname>-doc.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Template Used

    ``tendril/dox/templates/projects/geda-conf-doc.tex``
    (:download:`Included version
    <../../tendril/dox/templates/projects/geda-conf-doc.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``configname``
          - The name of the configuration (a card or cable name).
        * - ``desc``
          - The description of the configuration.
        * - ``pcbname``
          - The name of the base PCB.
        * - ``obom``
          - An :mod:`tendril.boms.outputbase.OutputBom` instance

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    outpath = path.join(docfolder, 'confdocs', configname + '-doc.pdf')
    outf_mtime = fsutils.get_file_mtime(outpath, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + outpath)
        return outpath

    logger.info('Regenerating ' + outpath + os.linesep +
                'Last modified : ' + str(sch_mtime) +
                '; Last Created : ' + str(outf_mtime))
    bom = boms_electronics.import_pcb(projfolder)
    obom = bom.create_output_bom(configname)
    group_oboms = bom.get_group_boms(configname)
    stage = {'configname': obom.descriptor.configname,
             'pcbname': obom.descriptor.pcbname,
             'bom': bom,
             'obom': obom,
             'group_oboms': group_oboms}

    config = obom.descriptor.configurations.configuration(configname)
    stage['desc'] = config['desc']

    template = 'projects/geda-conf-doc.tex'

    workspace_outpath = workspace_fs.getsyspath(outpath)
    workspace_fs.makedir(path.dirname(outpath),
                         recursive=True, allow_recreate=True)
    render.render_pdf(stage, template, workspace_outpath)
    copyfile(workspace_fs, outpath, refdoc_fs, outpath, overwrite=True)

    return outpath
Exemplo n.º 30
0
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
Exemplo n.º 31
0
def gen_pcb_gbr(projfolder, force=False):
    """
    Generates gerber files for the PCB provided by the gEDA project, and also
    creates a ``zip`` file of the generated gerbers.

    The pcbfile is the one listed in the gEDA project file, and the
    pcbname is the one specified in the
    :mod:`tendril.gedaif.conffile.ConfigsFile`.

    This function does not use jinja2 and latex. It relies on
    :func:`tendril.gedaif.pcb.conv_pcb2gbr` instead.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output Files :  ``<project_doc_folder>/../gerber/*``
    * Output Zip File : ``<project_doc_folder>/../<pcbfile>-gerber.zip``
    * Source Files : The project's `.pcb` file.

    """
    configfile = conffile.ConfigsFile(projfolder)
    gpf = projfile.GedaProjectFile(configfile.projectfolder)
    pcb_mtime = fsutils.get_file_mtime(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'))
    if pcb_mtime is None:
        logger.warning("PCB does not seem to exist for : " + projfolder)
        return
    docfolder = get_project_doc_folder(projfolder)
    imgfolder = os.path.join(docfolder, os.pardir, 'img')
    gbrfolder = os.path.join(docfolder, os.pardir, 'gerber')
    outf_mtime = None
    if not refdoc_fs.exists(gbrfolder):
        refdoc_fs.makedir(gbrfolder)
    else:
        outf_mtime = fsutils.get_folder_mtime(gbrfolder, fs=refdoc_fs)
    if not refdoc_fs.exists(imgfolder):
        refdoc_fs.makedir(imgfolder)

    if not force and outf_mtime is not None and outf_mtime > pcb_mtime:
        logger.debug('Skipping up-to-date ' + gbrfolder)
        return gbrfolder

    logger.info('Regenerating ' + gbrfolder + os.linesep + 'Last modified : ' +
                str(pcb_mtime) + '; Last Created : ' + str(outf_mtime))
    rf = refdoc_fs.listdir(gbrfolder, files_only=True, full=True)
    for f in rf:
        refdoc_fs.remove(f)

    workspace_folder = workspace_fs.getsyspath(gbrfolder)
    workspace_fs.makedir(gbrfolder, recursive=True, allow_recreate=True)

    gbrfolder = pcb.conv_pcb2gbr(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
        workspace_folder)

    workspace_fs.makedir(imgfolder, recursive=True, allow_recreate=True)

    img_workspace_folder = workspace_fs.getsyspath(imgfolder)
    gen_pcb_img(gbrfolder,
                outfolder=img_workspace_folder,
                outfname=gpf.pcbfile,
                force=False)

    for f in os.listdir(img_workspace_folder):
        fpath = os.path.relpath(os.path.join(img_workspace_folder, f),
                                workspace_fs.getsyspath('/'))
        copyfile(workspace_fs, fpath, refdoc_fs, fpath, overwrite=True)

    zfile = os.path.join(workspace_folder, os.pardir,
                         gpf.pcbfile + '-gerber.zip')
    fsutils.zipdir(gbrfolder, zfile)

    for f in os.listdir(workspace_folder):
        fpath = os.path.relpath(os.path.join(workspace_folder, f),
                                workspace_fs.getsyspath('/'))
        copyfile(workspace_fs, fpath, refdoc_fs, fpath, overwrite=True)
    zfpath = os.path.relpath(os.path.join(workspace_folder, zfile),
                             workspace_fs.getsyspath('/'))
    copyfile(workspace_fs, zfpath, refdoc_fs, zfpath, overwrite=True)

    return gbrfolder
Exemplo n.º 32
0
def gen_confpdf(projfolder, configname, namebase, force=False):
    """
    Generates a PDF file of the documentation for a specific configuration
    of a project. It uses other document generator functions to make the
    various parts of the master document and then merges them.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param configname: The name of the configuration.
    :type configname: 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>/confdocs/<configname>.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Included Documents

    * Configuration BOM, generated by :func:`gen_confbom`
    * (Full) Schematic PDF, generated by :func:`gen_schpdf`

    .. todo:: It may be useful to rebuild the schematics after removing
              all the unpopulated components. This is a fairly involved
              process, and is deferred until later.

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    confdocfile = path.join(docfolder, 'confdocs', configname + '.pdf')
    outf_mtime = fsutils.get_file_mtime(confdocfile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + confdocfile)
        return confdocfile

    logger.info('Regenerating ' + confdocfile + os.linesep +
                'Last modified : ' + str(sch_mtime) + '; Last Created : ' +
                str(outf_mtime))

    pdffiles = [
        gen_confbom(projfolder, configname, force),
        gen_confdoc(projfolder, configname, force),
        gen_schpdf(projfolder, namebase, configname=configname, force=force)
    ]

    for p in pdffiles:
        if p and not workspace_fs.exists(p):
            workspace_fs.makedir(path.dirname(p),
                                 recursive=True,
                                 allow_recreate=True)
            copyfile(refdoc_fs, p, workspace_fs, p)

    workspace_pdffiles = [
        workspace_fs.getsyspath(x) for x in pdffiles if x is not None
    ]

    workspace_outpath = workspace_fs.getsyspath(confdocfile)
    workspace_fs.makedir(path.dirname(confdocfile),
                         recursive=True,
                         allow_recreate=True)
    pdf.merge_pdf(workspace_pdffiles, workspace_outpath)
    copyfile(workspace_fs, confdocfile, refdoc_fs, confdocfile, overwrite=True)
    return confdocfile
Exemplo n.º 33
0
def gen_masterdoc(projfolder, namebase, force=False):
    """
    Generates a PDF file of the project's Master documentation. It uses
    other document generator functions to make the various parts of the
    master document and then merges them.

    .. note:: Due to the way groups and motifs are handled, an
              unconfigured BOM is somewhat meaningless. Therefore,
              no BOM is included in the masterdoc.

    :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>-masterdoc.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Included Documents

    * Config Documentation, generated by :func:`gen_configsdoc`
    * Schematic PDF, generated by :func:`gen_schpdf`

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    masterdocfile = path.join(docfolder, namebase + '-masterdoc.pdf')
    outf_mtime = fsutils.get_file_mtime(masterdocfile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + masterdocfile)
        return masterdocfile

    logger.info('Regnerating ' + masterdocfile + os.linesep +
                'Last modified : ' + str(sch_mtime) + '; Last Created : ' +
                str(outf_mtime))

    pdffiles = [
        gen_configsdoc(projfolder, namebase, force=False),
        gen_schpdf(projfolder, namebase, force=False)
    ]

    for p in pdffiles:
        if p and not workspace_fs.exists(p):
            workspace_fs.makedir(path.dirname(p),
                                 recursive=True,
                                 allow_recreate=True)
            copyfile(refdoc_fs, p, workspace_fs, p)

    workspace_pdffiles = [
        workspace_fs.getsyspath(x) for x in pdffiles if x is not None
    ]

    workspace_outpath = workspace_fs.getsyspath(masterdocfile)
    workspace_fs.makedir(path.dirname(masterdocfile),
                         recursive=True,
                         allow_recreate=True)
    pdf.merge_pdf(workspace_pdffiles, workspace_outpath)
    copyfile(workspace_fs,
             masterdocfile,
             refdoc_fs,
             masterdocfile,
             overwrite=True)
    return masterdocfile
Exemplo n.º 34
0
def gen_schpdf(projfolder, namebase, configname=None, force=False):
    """
    Generates a PDF file of all the project schematics listed in the
    gEDA project file. This function does not use jinja2 and latex. It
    relies on :func:`tendril.gedaif.gschem.conv_gsch2pdf` 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>-schematic.pdf``
    * Source Files : The project's schematic folder.

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    configfile = conffile.ConfigsFile(projfolder)
    docfolder = get_project_doc_folder(projfolder)

    # TODO Consider converting all configurations in one go instead?
    if configname is None:
        schpdfpath = path.join(docfolder, namebase + '-schematic.pdf')
    else:
        docfolder = path.join(docfolder, 'confdocs')
        pdfname = configname + '-conf-schematic.pdf'
        schpdfpath = path.join(docfolder, pdfname)
    outf_mtime = fsutils.get_file_mtime(schpdfpath, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + schpdfpath)
        return schpdfpath

    logger.info('Regenerating ' + schpdfpath + os.linesep +
                'Last modified : ' + str(sch_mtime) + '; Last Created : ' +
                str(outf_mtime))

    if configfile.rawconfig is not None:
        workspace_outpath = workspace_fs.getsyspath(schpdfpath)
        workspace_folder = workspace_fs.getsyspath(docfolder)
        workspace_fs.makedir(docfolder, recursive=True, allow_recreate=True)
        pdffiles = []
        obom = None
        if configname is not None:
            tfolder = path.join(docfolder, configname)
            workspace_tfolder = workspace_fs.getsyspath(tfolder)
            workspace_fs.makedir(tfolder, recursive=False, allow_recreate=True)
            bom = boms_electronics.import_pcb(projfolder)
            bom.configure_motifs(configname)
            obom = bom.create_output_bom(configname)
        for schematic in gpf.schfiles:
            schfile = os.path.normpath(projfolder + '/schematic/' + schematic)
            if configname is not None:
                tschfile = path.join(workspace_tfolder, schematic)
                gschem.rewrite_schematic(schfile, obom, gpf, tschfile)
                pdffile = gschem.conv_gsch2pdf(tschfile, workspace_tfolder)
                os.remove(tschfile)
            else:
                pdffile = gschem.conv_gsch2pdf(schfile, workspace_folder)
            pdffiles.append(pdffile)
        pdf.merge_pdf(pdffiles, workspace_outpath)
        for pdffile in pdffiles:
            os.remove(pdffile)
        copyfile(workspace_fs,
                 schpdfpath,
                 refdoc_fs,
                 schpdfpath,
                 overwrite=True)
        return schpdfpath
Exemplo n.º 35
0
def gen_confdoc(projfolder, configname, force=False):
    """
    Generate a PDF documenting a single configuration of the project. The
    document should include a reasonably thorough representation of the
    contents of the configuration related sections of the
    `tendril.gedaif.conffile.ConfigsFile``.

    :param projfolder: The gEDA project folder
    :type projfolder: str
    :param configname: The configuration name for which the BOM should be
                       generated.
    :type configname: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output File :  ``<project_doc_folder>/confdocs/<configname>-doc.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Template Used

    ``tendril/dox/templates/projects/geda-conf-doc.tex``
    (:download:`Included version
    <../../tendril/dox/templates/projects/geda-conf-doc.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``configname``
          - The name of the configuration (a card or cable name).
        * - ``desc``
          - The description of the configuration.
        * - ``pcbname``
          - The name of the base PCB.
        * - ``obom``
          - An :mod:`tendril.boms.outputbase.OutputBom` instance

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    outpath = path.join(docfolder, 'confdocs', configname + '-doc.pdf')
    outf_mtime = fsutils.get_file_mtime(outpath, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + outpath)
        return outpath

    logger.info('Regenerating ' + outpath + os.linesep + 'Last modified : ' +
                str(sch_mtime) + '; Last Created : ' + str(outf_mtime))
    bom = boms_electronics.import_pcb(projfolder)
    obom = bom.create_output_bom(configname)
    group_oboms = bom.get_group_boms(configname)
    stage = {
        'configname': obom.descriptor.configname,
        'pcbname': obom.descriptor.pcbname,
        'bom': bom,
        'obom': obom,
        'group_oboms': group_oboms
    }

    config = obom.descriptor.configurations.configuration(configname)
    stage['desc'] = config['desc']

    template = 'projects/geda-conf-doc.tex'

    workspace_outpath = workspace_fs.getsyspath(outpath)
    workspace_fs.makedir(path.dirname(outpath),
                         recursive=True,
                         allow_recreate=True)
    render.render_pdf(stage, template, workspace_outpath)
    copyfile(workspace_fs, outpath, refdoc_fs, outpath, overwrite=True)

    return outpath
Exemplo n.º 36
0
def gen_confpdf(projfolder, configname, namebase, force=False):
    """
    Generates a PDF file of the documentation for a specific configuration
    of a project. It uses other document generator functions to make the
    various parts of the master document and then merges them.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param configname: The name of the configuration.
    :type configname: 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>/confdocs/<configname>.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Included Documents

    * Configuration BOM, generated by :func:`gen_confbom`
    * (Full) Schematic PDF, generated by :func:`gen_schpdf`

    .. todo:: It may be useful to rebuild the schematics after removing
              all the unpopulated components. This is a fairly involved
              process, and is deferred until later.

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    confdocfile = path.join(docfolder, 'confdocs', configname + '.pdf')
    outf_mtime = fsutils.get_file_mtime(confdocfile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + confdocfile)
        return confdocfile

    logger.info('Regenerating ' + confdocfile + os.linesep +
                'Last modified : ' + str(sch_mtime) +
                '; Last Created : ' + str(outf_mtime))

    pdffiles = [gen_confbom(projfolder, configname, force),
                gen_confdoc(projfolder, configname, force),
                gen_schpdf(projfolder, namebase, force)]

    for p in pdffiles:
        if p and not workspace_fs.exists(p):
            workspace_fs.makedir(path.dirname(p),
                                 recursive=True, allow_recreate=True)
            copyfile(refdoc_fs, p, workspace_fs, p)

    workspace_pdffiles = [workspace_fs.getsyspath(x)
                          for x in pdffiles if x is not None]

    workspace_outpath = workspace_fs.getsyspath(confdocfile)
    workspace_fs.makedir(path.dirname(confdocfile),
                         recursive=True, allow_recreate=True)
    pdf.merge_pdf(workspace_pdffiles, workspace_outpath)
    copyfile(workspace_fs, confdocfile,
             refdoc_fs, confdocfile,
             overwrite=True)
    return confdocfile
Exemplo n.º 37
0
 def _update_files(self, src, dst, path, src_i, dst_i, files, truncated= False, depth= 0, cached_status= None,verbose=True):
     if verbose and files: print "\t"*depth+"Update files"
     status= cached_status
     for file, sinfo, dinfo in files:
         if verbose: print "\t"*depth+"Object: "+file
         if not cached_status or not self.cache_file_status:
             (truncated, status)= self.config.GetPathStatus(path+[file], True)
             
         if status==PathStatus.include:
             src_index= None
             dst_index= None
             src_mtime= sinfo["modified_time"]
             src_filesize= src.getsize(file)
             dst_mtime= dinfo["modified_time"]
             dst_filesize= dst.getsize(file)
             
             if verbose: print "\t"*depth+"Synching file"
             if src_filesize>1000 or dst_filesize>1000:
                 src_index= src_i.GetPathPart([src_i.name,file], True)
                 dst_index= dst_i.GetPathPart([dst_i.name,file], True)
             #If we get error when getting indexes, just action based on scr or dst mtime
             if src_index==None or dst_index==None:
                 if src_mtime>dst_mtime:
                     try:
                         copyfile(src, file, dst, file)
                     except:
                         continue
                 else:
                     try:
                         copyfile(dst, file, src, file)
                     except:
                         continue
             #Create index time, if it does not exist yet.
             elif src_index.CreationTime==None or dst_index.CreationTime==None:
                 if verbose: print "\t"*depth+"No index time found."
                 if src_mtime>dst_mtime:
                     try:
                         copyfile(src, file, dst, file)
                     except:
                         continue
                     src_index.CreationTime= self.dt2ut(src_mtime)
                     dst_index.CreationTime= self.dt2ut(dst.getinfo(file)["modified_time"])
                 else:
                     try:
                         copyfile(dst, file, src, file)
                     except:
                         continue
                     dst_index.CreationTime= self.dt2ut(dst_mtime)
                     src_index.CreationTime= self.dt2ut(src.getinfo(file)["modified_time"])
             #When indexes exist
             else:    
                 #both files are unchanged
                 if self.SmallTime(src_mtime, self.ut2dt(src_index.CreationTime)) and self.SmallTime(dst_mtime, self.ut2dt(dst_index.CreationTime)):
                     if verbose: print "\t"*depth+"Both files are synched"
                 #src has changed and dst has not
                 elif self.ut2dt(src_index.CreationTime)<src_mtime and self.SmallTime(dst_mtime, self.ut2dt(dst_index.CreationTime)):
                     if verbose: print "\t"*depth+"Src file has changed, but dst not"
                     try:
                         copyfile(src, file, dst, file)
                     except:
                         continue
                     dst_index.CreationTime= self.dt2ut(dst.getinfo(file)["modified_time"])
                 #dst has changed and src has not
                 elif self.ut2dt(dst_index.CreationTime)<dst_mtime and self.SmallTime(src_mtime, self.ut2dt(src_index.CreationTime)):
                     if verbose: print "\t"*depth+"Dst file has changed, but src not"
                     try:
                         copyfile(dst, file, src, file)
                     except:
                         continue
                     src_index.CreationTime= self.dt2ut(src.getinfo(file)["modified_time"])
                 #both files has changed, update indexes 
                 elif not self.SmallTime(src_mtime, self.ut2dt(src_index.CreationTime)) and not self.SmallTime(dst_mtime, self.ut2dt(dst_index.CreationTime)):
                     if verbose: print "\t"*depth+"Both files has changed."
                     if src_mtime>dst_mtime:
                         try:
                             copyfile(src, file, dst, file)
                         except:
                             continue
                         src_index.CreationTime= self.dt2ut(src_mtime)
                         dst_index.CreationTime= self.dt2ut(dst.getinfo(file)["modified_time"])
                     else:
                         try:
                             copyfile(dst, file, src, file)
                         except:
                             continue
                         dst_index.CreationTime= self.dt2ut(dst_mtime)
                         src_index.CreationTime= self.dt2ut(src.getinfo(file)["modified_time"])
         #If we have stop on file just delete it on both sides
         if status==PathStatus.stop:
             if verbose: print "\t"*depth+"Removing file"
             src.remove(file)
             dst.remove(file)
Exemplo n.º 38
0
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
Exemplo n.º 39
0
    def _accessor(self, max_age, getcpath=False, *args, **kwargs):
        """
        The primary accessor for the cache instance. Each subclass should
        provide a function which behaves similarly to that of the original,
        un-cached version of the resource getter. That function should adapt
        the parameters provided to it into the form needed for this one, and
        let this function maintain the cached responses and handle retrieval
        of the response.

        If the module's :data:`_internet_connected` is set to False, the
        cached value is returned regardless.

        """
        filepath = self._get_filepath(*args, **kwargs)
        send_cached = False
        if not _internet_connected and self._cached_exists(filepath):
            send_cached = True
        if self._is_cache_fresh(filepath, max_age):
            logger.debug("Cache HIT")
            send_cached = True
        if send_cached is True:
            if getcpath is False:
                try:
                    filecontent = self.cache_fs.open(filepath, 'rb').read()
                    return self._deserialize(filecontent)
                except UnicodeDecodeError:
                    # TODO This requires the cache_fs to be a local
                    # filesystem. This may not be very nice. A way
                    # to hook codecs upto to pyfilesystems would be better
                    with codecs.open(
                            self.cache_fs.getsyspath(filepath),
                            encoding='utf-8') as f:
                        filecontent = f.read()
                        return self._deserialize(filecontent)
            else:
                return self.cache_fs.getsyspath(filepath)

        logger.debug("Cache MISS")
        data = self._get_fresh_content(*args, **kwargs)
        try:
            sdata = self._serialize(data)
            fd, temppath = tempfile.mkstemp()
            fp = os.fdopen(fd, 'wb')
            fp.write(sdata)
            fp.close()
            logger.debug("Creating new cache entry")
            # This can be pretty expensive if the move is across a real filesystem
            # boundary. We should instead use a temporary file in the cache_fs
            # itself
            try:
                copyfile(temp_fs, temp_fs.unsyspath(temppath),
                         self.cache_fs, filepath)
            except:
                logger.warning("Unable to write cache file {0}".format(filepath))
        except:
            raise

        if getcpath is False:
            return data
        else:
            return self.cache_fs.getsyspath(filepath)
Exemplo n.º 40
0
def gen_pcb_gbr(projfolder, force=False):
    """
    Generates gerber files for the PCB provided by the gEDA project, and also
    creates a ``zip`` file of the generated gerbers.

    The pcbfile is the one listed in the gEDA project file, and the
    pcbname is the one specified in the
    :mod:`tendril.gedaif.conffile.ConfigsFile`.

    This function does not use jinja2 and latex. It relies on
    :func:`tendril.gedaif.pcb.conv_pcb2gbr` instead.

    :param projfolder: The gEDA project folder.
    :type projfolder: str
    :param force: Regenerate even if up-to-date.
    :type force: bool
    :return: The output file path.

    .. rubric:: Paths

    * Output Files :  ``<project_doc_folder>/../gerber/*``
    * Output Zip File : ``<project_doc_folder>/../<pcbfile>-gerber.zip``
    * Source Files : The project's `.pcb` file.

    """
    configfile = conffile.ConfigsFile(projfolder)
    gpf = projfile.GedaProjectFile(configfile.projectfolder)
    pcb_mtime = fsutils.get_file_mtime(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb')
    )
    if pcb_mtime is None:
        logger.warning("PCB does not seem to exist for : " + projfolder)
        return
    docfolder = get_project_doc_folder(projfolder)
    imgfolder = os.path.join(docfolder, os.pardir, 'img')
    gbrfolder = os.path.join(docfolder, os.pardir, 'gerber')
    outf_mtime = None
    if not refdoc_fs.exists(gbrfolder):
        refdoc_fs.makedir(gbrfolder)
    else:
        outf_mtime = fsutils.get_folder_mtime(gbrfolder, fs=refdoc_fs)
    if not refdoc_fs.exists(imgfolder):
        refdoc_fs.makedir(imgfolder)

    if not force and outf_mtime is not None and outf_mtime > pcb_mtime:
        logger.debug('Skipping up-to-date ' + gbrfolder)
        return gbrfolder

    logger.info('Regenerating ' + gbrfolder + os.linesep +
                'Last modified : ' + str(pcb_mtime) +
                '; Last Created : ' + str(outf_mtime))
    rf = refdoc_fs.listdir(gbrfolder, files_only=True, full=True)
    for f in rf:
        refdoc_fs.remove(f)

    workspace_folder = workspace_fs.getsyspath(gbrfolder)
    workspace_fs.makedir(gbrfolder,
                         recursive=True, allow_recreate=True)

    gbrfolder = pcb.conv_pcb2gbr(
        os.path.join(configfile.projectfolder, 'pcb', gpf.pcbfile + '.pcb'),
        workspace_folder
    )

    workspace_fs.makedir(imgfolder,
                         recursive=True, allow_recreate=True)

    img_workspace_folder = workspace_fs.getsyspath(imgfolder)
    gen_pcb_img(gbrfolder, outfolder=img_workspace_folder,
                outfname=gpf.pcbfile, force=False)

    for f in os.listdir(img_workspace_folder):
        fpath = os.path.relpath(
            os.path.join(img_workspace_folder, f), workspace_fs.getsyspath('/')
        )
        copyfile(workspace_fs, fpath, refdoc_fs, fpath, overwrite=True)

    zfile = os.path.join(
        workspace_folder, os.pardir, gpf.pcbfile + '-gerber.zip'
    )
    fsutils.zipdir(gbrfolder, zfile)

    for f in os.listdir(workspace_folder):
        fpath = os.path.relpath(
            os.path.join(workspace_folder, f), workspace_fs.getsyspath('/')
        )
        copyfile(workspace_fs, fpath, refdoc_fs, fpath, overwrite=True)
    zfpath = os.path.relpath(
        os.path.join(workspace_folder, zfile), workspace_fs.getsyspath('/')
    )
    copyfile(workspace_fs, zfpath, refdoc_fs, zfpath, overwrite=True)

    return gbrfolder
Exemplo n.º 41
0
def gen_masterdoc(projfolder, namebase, force=False):
    """
    Generates a PDF file of the project's Master documentation. It uses
    other document generator functions to make the various parts of the
    master document and then merges them.

    .. note:: Due to the way groups and motifs are handled, an
              unconfigured BOM is somewhat meaningless. Therefore,
              no BOM is included in the masterdoc.

    :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>-masterdoc.pdf``
    * Source Files : The project's schematic folder.

    .. rubric:: Included Documents

    * Config Documentation, generated by :func:`gen_configsdoc`
    * Schematic PDF, generated by :func:`gen_schpdf`

    """
    gpf = projfile.GedaProjectFile(projfolder)
    sch_mtime = fsutils.get_folder_mtime(gpf.schfolder)

    docfolder = get_project_doc_folder(projfolder)
    masterdocfile = path.join(docfolder, namebase + '-masterdoc.pdf')
    outf_mtime = fsutils.get_file_mtime(masterdocfile, fs=refdoc_fs)

    if not force and outf_mtime is not None and outf_mtime > sch_mtime:
        logger.debug('Skipping up-to-date ' + masterdocfile)
        return masterdocfile

    logger.info('Regnerating ' + masterdocfile + os.linesep +
                'Last modified : ' + str(sch_mtime) +
                '; Last Created : ' + str(outf_mtime))

    pdffiles = [gen_configsdoc(projfolder, namebase, force=False),
                gen_schpdf(projfolder, namebase, force=False)]

    for p in pdffiles:
        if p and not workspace_fs.exists(p):
            workspace_fs.makedir(path.dirname(p),
                                 recursive=True, allow_recreate=True)
            copyfile(refdoc_fs, p, workspace_fs, p)

    workspace_pdffiles = [workspace_fs.getsyspath(x)
                          for x in pdffiles if x is not None]

    workspace_outpath = workspace_fs.getsyspath(masterdocfile)
    workspace_fs.makedir(path.dirname(masterdocfile),
                         recursive=True, allow_recreate=True)
    pdf.merge_pdf(workspace_pdffiles, workspace_outpath)
    copyfile(workspace_fs, masterdocfile,
             refdoc_fs, masterdocfile,
             overwrite=True)
    return masterdocfile