Пример #1
0
    def main(self):

        documents = self.get_db().query(self.args.search)

        if self.args.json and self.args.folder or \
           self.args.yaml and self.args.folder:
            self.logger.warning("Only --folder flag will be considered")

        if not self.args.all:
            document = self.pick(documents)
            if not document:
                return 0
            documents = [document]

        if self.args.out and not self.get_args().folder \
        and not self.args.file:
            self.args.out = open(self.get_args().out, 'a+')

        if not self.args.out and not self.get_args().folder \
        and not self.args.file:
            self.args.out = sys.stdout

        ret_string = run(documents,
                         yaml=self.args.yaml,
                         bibtex=self.args.bibtex,
                         json=self.args.json,
                         text=self.args.text)

        if ret_string is not None:
            self.args.out.write(ret_string)
            return 0

        for document in documents:
            if self.args.folder:
                folder = document.get_main_folder()
                outdir = self.args.out or document.get_main_folder_name()
                if not len(documents) == 1:
                    outdir = os.path.join(outdir,
                                          document.get_main_folder_name())
                shutil.copytree(folder, outdir)
                if not self.args.no_bibtex:
                    open(os.path.join(outdir, "info.bib"),
                         "a+").write(papis.document.to_bibtex(document))
            elif self.args.file:
                files = document.get_files()
                if self.args.all:
                    files_to_open = files
                else:
                    files_to_open = [
                        papis.api.pick(
                            files,
                            pick_config=dict(header_filter=lambda x: x.replace(
                                document.get_main_folder(), "")))
                    ]
                for file_to_open in filter(lambda x: x, files_to_open):
                    print(file_to_open)
                    shutil.copyfile(
                        file_to_open, self.args.out
                        or os.path.basename(file_to_open))
Пример #2
0
def cli(query, yaml, bibtex, json, folder, out, text, all, file):
    """Export a document from a given library"""

    logger = logging.getLogger('cli:export')
    documents = papis.database.get().query(query)

    if json and folder or yaml and folder:
        logger.warning("Only --folder flag will be considered")

    if not all:
        document = papis.api.pick_doc(documents)
        if not document:
            return 0
        documents = [document]

    ret_string = run(documents, yaml=yaml, bibtex=bibtex, json=json, text=text)

    if ret_string is not None:
        if out is not None:
            logger.info("Dumping to {0}".format(out))
            with open(out, 'w+') as fd:
                fd.write(ret_string)
        else:
            logger.info("Dumping to stdout")
            print(ret_string)
        return 0

    for document in documents:
        if folder:
            folder = document.get_main_folder()
            outdir = out or document.get_main_folder_name()
            if not len(documents) == 1:
                outdir = os.path.join(outdir, document.get_main_folder_name())
            shutil.copytree(folder, outdir)
        elif file:
            logger.info("Exporting file")
            files = document.get_files()
            assert (isinstance(files, list))
            if not files:
                logger.error('No files found for doc in {0}'.format(
                    document.get_main_folder()))
                continue
            files_to_open = [
                papis.api.pick(
                    files,
                    pick_config=dict(header_filter=lambda x: x.replace(
                        document.get_main_folder(), "")))
            ]
            files_to_copy = list(filter(lambda x: x, files_to_open))
            for file_to_open in files_to_copy:

                if out is not None and len(files_to_open) == 1:
                    out_file = out
                else:
                    out_file = os.path.basename(file_to_open)

                logger.info("copy {0} to {1}".format(file_to_open, out_file))
                shutil.copyfile(file_to_open, out_file)
Пример #3
0
def cli(query: str, git: bool, sort_field: Optional[str], doc_folder: str,
        sort_reverse: bool) -> None:
    """Rename entry"""

    if doc_folder:
        documents = [papis.document.from_folder(doc_folder)]
    else:
        documents = papis.database.get().query(query)

    if sort_field:
        documents = papis.document.sort(documents, sort_field, sort_reverse)

    logger = logging.getLogger('cli:rename')

    if not documents:
        logger.warning(papis.strings.no_documents_retrieved_message)
    docs = papis.pick.pick_doc(documents)
    if not docs:
        return

    document = docs[0]

    new_name = papis.tui.utils.prompt(
        "Enter new folder name:\n"
        ">",
        default=document.get_main_folder_name() or '')
    run(document, new_name, git=git)
Пример #4
0
    def add(self,
            doc_manager=None,
            document=None,
            folder_name=None,
            key=None,
            value=None,
            doc=False,
            file=False,
            file_name=None):

        if doc_manager is not None:
            document = doc_manager.get_document()
            folder_name = document.get_main_folder_name()

        folder_path = self.get_folder_path(folder_name)

        if file or doc:
            self.add_file(folder_name,
                          file_path=value,
                          file_name=file_name,
                          doc=doc,
                          file=file)

        if file:
            document.set_key(key, file_name, append=True)
            document.save()
            self.update(document)

        elif doc:
            document = papis.document.Document(folder_path, document)
            document.save(data=document)
            self._database.add(document)

        return document
Пример #5
0
    def move_files_to_shared_library(self, document, validation=False):

        folder_name = document.get_main_folder_name()

        for library in self._library:
            folder_path = self.get_folder_path(folder_name,
                                               library=library.get_path())

            files = []
            if os.path.exists(folder_path):
                files = [
                    f for f in os.listdir(folder_path)
                    if os.path.isfile(os.path.join(folder_path, f))
                ]

            extension, include = self.get_extension_to_ignore(library)

            for f in files:
                if not self.is_extension_in_library(f, extension, include):
                    if validation:
                        return False
                    self.add_file(folder_name,
                                  file_path=os.path.join(folder_path, f),
                                  file=True,
                                  file_name=os.path.basename(f))
                    os.unlink(os.path.join(folder_path, f))

        if validation:
            return True
Пример #6
0
def cli(query: str,
        doc_folder: str,
        sort_field: Optional[str],
        sort_reverse: bool,
        folder: str,
        out: str,
        fmt: str,
        _all: bool) -> None:
    """Export a document from a given library"""

    if doc_folder:
        documents = [papis.document.from_folder(doc_folder)]
    else:
        documents = papis.database.get().query(query)

    if fmt and folder:
        logger.warning("Only --folder flag will be considered")

    if not documents:
        logger.warning(papis.strings.no_documents_retrieved_message)
        return

    if not _all:
        documents = [d for d in papis.pick.pick_doc(documents)]
        if not documents:
            return

    if sort_field:
        documents = papis.document.sort(documents, sort_field, sort_reverse)

    # Get the local folder of the document so that third-party apps
    # can actually go to the folder without checking with papis
    for d in documents:
        d["_papis_local_folder"] = d.get_main_folder()

    ret_string = run(documents, to_format=fmt)

    if ret_string is not None and not folder:
        if out is not None:
            logger.info("Dumping to {0}".format(out))
            with open(out, 'a+') as fd:
                fd.write(ret_string)
        else:
            logger.info("Dumping to stdout")
            print(ret_string)
        return

    for document in documents:
        if folder:
            _doc_folder = document.get_main_folder()
            _doc_folder_name = document.get_main_folder_name()
            outdir = out or _doc_folder_name
            if not _doc_folder or not _doc_folder_name or not outdir:
                raise Exception(papis.strings.no_folder_attached_to_document)
            if not len(documents) == 1:
                outdir = os.path.join(out, _doc_folder_name)
            logger.info("Exporting doc {0} to {1}".format(
                papis.document.describe(document), outdir
            ))
            shutil.copytree(_doc_folder, outdir)
Пример #7
0
def cli(query, folder, out, format, all, **kwargs):
    """Export a document from a given library"""

    documents = papis.database.get().query(query)

    if format and folder:
        logger.warning("Only --folder flag will be considered")

    if not documents:
        logger.warning(papis.strings.no_documents_retrieved_message)
        return

    if not all:
        document = papis.api.pick_doc(documents)
        if not document:
            return 0
        documents = [document]

    ret_string = run(
        documents,
        to_format=format,
    )

    if ret_string is not None and not folder:
        if out is not None:
            logger.info("Dumping to {0}".format(out))
            with open(out, 'a+') as fd:
                fd.write(ret_string)
        else:
            logger.info("Dumping to stdout")
            print(ret_string)
        return 0

    for document in documents:
        if folder:
            folder = document.get_main_folder()
            outdir = out or document.get_main_folder_name()
            if not len(documents) == 1:
                outdir = os.path.join((out or ''),
                                      document.get_main_folder_name())
            logger.info("Exporting doc {0} to {1}".format(
                papis.document.describe(document), outdir))
            shutil.copytree(folder, outdir)
Пример #8
0
def cli(query: str, git: bool, sort_field: Optional[str], doc_folder: str,
        sort_reverse: bool) -> None:
    """Move a document into some other path"""
    # Leave this imports here for performance
    import prompt_toolkit
    import prompt_toolkit.completion

    logger = logging.getLogger('cli:mv')

    if doc_folder:
        documents = [papis.document.from_folder(doc_folder)]
    else:
        documents = papis.database.get().query(query)

    if not documents:
        logger.warning(papis.strings.no_documents_retrieved_message)
        return

    if sort_field:
        documents = papis.document.sort(documents, sort_field, sort_reverse)

    docs = papis.pick.pick_doc(documents)
    if not docs:
        return
    document = docs[0]

    lib_dir = os.path.expanduser(papis.config.get_lib_dirs()[0])

    completer = prompt_toolkit.completion.PathCompleter(
        only_directories=True, get_paths=lambda: [lib_dir])

    try:
        new_folder = os.path.join(
            lib_dir,
            prompt_toolkit.prompt(
                message=("Enter directory  : (Tab completion enabled)\n"
                         "Current directory: ({dir})\n".format(
                             dir=document.get_main_folder_name()) + ">  "),
                completer=completer,
                complete_while_typing=True))
    except Exception as e:
        logger.error(e)
        return

    logger.info(new_folder)

    if not os.path.exists(new_folder):
        logger.info("Creating path %s" % new_folder)
        os.makedirs(new_folder, mode=papis.config.getint('dir-umask') or 0o666)

    run(document, new_folder, git=git)
Пример #9
0
    def main(self):
        if papis.config.in_mode("contact"):
            self.init_contact_mode()
        lib_dir = os.path.expanduser(papis.config.get('dir'))
        data = dict()
        # The folder name of the new document that will be created
        out_folder_name = None
        # The real paths of the documents to be added
        in_documents_paths = self.args.document
        # The basenames of the documents to be added
        in_documents_names = []
        # The folder name of the temporary document to be created
        temp_dir = tempfile.mkdtemp("-"+self.args.lib)

        if self.args.from_lib:
            doc = self.pick(
                papis.api.get_documents_in_lib(self.get_args().from_lib)
            )
            if doc:
                self.args.from_folder = doc.get_main_folder()

        if self.args.from_folder:
            original_document = papis.document.Document(self.args.from_folder)
            self.args.from_yaml = original_document.get_info_file()
            in_documents_paths = original_document.get_files()

        if self.args.from_url:
            url_data = papis.downloaders.utils.get(self.args.from_url)
            data.update(url_data["data"])
            in_documents_paths.extend(url_data["documents_paths"])
            # If no data was retrieved and doi was found, try to get
            # information with the document's doi
            if not data and url_data["doi"] is not None and\
                not self.args.from_doi:
                self.logger.warning(
                    "I could not get any data from %s" % self.args.from_url
                )
                self.args.from_doi = url_data["doi"]

        if self.args.from_bibtex:
            bib_data = papis.bibtex.bibtex_to_dict(self.args.from_bibtex)
            if len(bib_data) > 1:
                self.logger.warning(
                    'Your bibtex file contains more than one entry,'
                    ' I will be taking the first entry'
                )
            data.update(bib_data[0])

        if self.args.from_pmid:
            self.logger.debug(
                "I'll try using PMID %s via HubMed" % self.args.from_pmid
            )
            hubmed_url = "http://pubmed.macropus.org/articles/"\
                         "?format=text%%2Fbibtex&id=%s" % self.args.from_pmid
            bibtex_data = papis.downloaders.utils.get_downloader(
                hubmed_url,
                "get"
            ).get_document_data().decode("utf-8")
            bibtex_data = papis.bibtex.bibtex_to_dict(bibtex_data)
            if len(bibtex_data):
                data.update(bibtex_data[0])
                if "doi" in data and not self.args.from_doi:
                    self.args.from_doi = data["doi"]
            else:
                self.logger.error(
                    "PMID %s not found or invalid" % self.args.from_pmid
                )

        if self.args.from_doi:
            self.logger.debug("I'll try using doi %s" % self.args.from_doi)
            data.update(papis.utils.doi_to_data(self.args.from_doi))
            if len(self.get_args().document) == 0 and \
                    papis.config.get('doc-url-key-name') in data.keys():
                doc_url = data[papis.config.get('doc-url-key-name')]
                self.logger.info(
                    'I am trying to download the document from %s' % doc_url
                )
                down = papis.downloaders.utils.get_downloader(
                    doc_url,
                    'get'
                )
                file_name = tempfile.mktemp()
                with open(file_name, 'wb+') as fd:
                    fd.write(down.get_document_data())
                self.logger.info('Opening the file')
                papis.api.open_file(file_name)
                if papis.utils.confirm('Do you want to use this file?'):
                    self.args.document.append(file_name)

        if self.args.from_yaml:
            self.logger.debug("Yaml input file = %s" % self.args.from_yaml)
            data.update(papis.utils.yaml_to_data(self.args.from_yaml))

        if self.args.from_vcf:
            data.update(papis.utils.vcf_to_data(self.args.from_vcf))
        in_documents_names = [
            papis.utils.clean_document_name(doc_path)
            for doc_path in in_documents_paths
        ]

        # Decide if we are adding the documents to an already existing document
        # or it is a new document
        if self.args.to:
            self.logger.debug(
                "Searching for the document where to add the files"
            )
            documents = papis.api.get_documents_in_dir(
                lib_dir,
                self.args.to
            )
            document = self.pick(documents)
            if not document: return 0
            document.update(
                data,
                interactive=self.args.interactive
            )
            document.save()
            data = document.to_dict()
            in_documents_paths = document.get_files() + in_documents_paths
            data["files"] = [os.path.basename(f) for f in in_documents_paths]
            # set out folder name the folder of the found document
            out_folder_name = document.get_main_folder_name()
            out_folder_path = document.get_main_folder()
        else:
            document = papis.document.Document(temp_dir)
            if not papis.config.in_mode("contact"):
                if len(in_documents_paths) == 0:
                    if not self.get_args().no_document:
                        self.logger.error("No documents to be added")
                        return 1
                    else:
                        in_documents_paths = [document.get_info_file()]
                        # We need the names to add them in the file field
                        # in the info file
                        in_documents_names = [papis.utils.get_info_file_name()]
                        # Save document to create the info file
                        document.update(
                            data, force=True, interactive=self.args.interactive
                        )
                        document.save()
                data["title"] = self.args.title or self.get_default_title(
                    data,
                    in_documents_paths[0]
                )
                data["author"] = self.args.author or self.get_default_author(
                    data,
                    in_documents_paths[0]
                )
                self.logger.debug("Author = % s" % data["author"])
                self.logger.debug("Title = % s" % data["title"])

            if not self.args.name:
                self.logger.debug("Getting an automatic name")
                out_folder_name = self.get_hash_folder(
                    data,
                    in_documents_paths[0]
                )
            else:
                temp_doc = papis.document.Document(data=data)
                out_folder_name = papis.utils.format_doc(
                    self.args.name,
                    temp_doc
                )
                out_folder_name = papis.utils.clean_document_name(
                    out_folder_name
                )
                del temp_doc
            if len(out_folder_name) == 0:
                self.logger.error('The output folder name is empty')
                return 1

            data["files"] = in_documents_names
            out_folder_path = os.path.join(
                lib_dir, self.args.dir,  out_folder_name
            )

        self.logger.debug("Folder name = % s" % out_folder_name)
        self.logger.debug("Folder path = % s" % out_folder_path)
        self.logger.debug("File(s)     = % s" % in_documents_paths)

        # Create folders if they do not exists.
        if not os.path.isdir(temp_dir):
            self.logger.debug("Creating directory '%s'" % temp_dir)
            os.makedirs(temp_dir, mode=papis.config.getint('dir-umask'))

        # Check if the user wants to edit before submitting the doc
        # to the library
        if self.args.edit:
            document.update(
                data, force=True, interactive=self.args.interactive
            )
            document.save()
            self.logger.debug("Editing file before adding it")
            papis.api.edit_file(document.get_info_file())
            self.logger.debug("Loading the changes made by editing")
            document.load()
            data = document.to_dict()

        # First prepare everything in the temporary directory
        for i in range(min(len(in_documents_paths), len(data["files"]))):
            in_doc_name = data["files"][i]
            in_file_path = in_documents_paths[i]
            assert(os.path.exists(in_file_path))
            endDocumentPath = os.path.join(
                document.get_main_folder(),
                in_doc_name
            )
            if os.path.exists(endDocumentPath):
                self.logger.debug(
                    "%s already exists, ignoring..." % endDocumentPath
                )
                continue
            if not self.args.no_document:
                self.logger.debug(
                    "[CP] '%s' to '%s'" %
                    (in_file_path, endDocumentPath)
                )
                shutil.copy(in_file_path, endDocumentPath)

        # Duplication checking
        self.logger.debug("Check if the added document is already existing")
        found_document = papis.utils.locate_document(
            document, papis.api.get_documents_in_lib(papis.api.get_lib())
        )
        if found_document is not None:
            self.logger.warning("DUPLICATION WARNING")
            self.logger.warning(
                "This document seems to be already in your libray: \n\n" +
                found_document.dump()
            )
            self.logger.warning(
                "Use the update command if you just want to update the info."
            )
            self.args.confirm = True

        document.update(data, force=True)
        if self.get_args().open:
            for d_path in in_documents_paths:
                papis.api.open_file(d_path)
        if self.args.confirm:
            if not papis.utils.confirm('Really add?'):
                return 0
        document.save()
        if self.args.to:
            return 0
        self.logger.debug(
            "[MV] '%s' to '%s'" %
            (document.get_main_folder(), out_folder_path)
        )
        shutil.move(document.get_main_folder(), out_folder_path)
        # Let us chmod it because it might come from a temp folder
        # and temp folders are per default 0o600
        os.chmod(out_folder_path, papis.config.getint('dir-umask'))
        papis.api.clear_lib_cache()
        if self.args.commit and papis.utils.lib_is_git_repo(self.args.lib):
            subprocess.call(["git", "-C", out_folder_path, "add", "."])
            subprocess.call(
                ["git", "-C", out_folder_path, "commit", "-m", "Add document"]
            )