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))
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)
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)
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
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
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)
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)
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)
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"] )