def _import_records(self, node, records): ''' shared backend for insertion of references retrieved from pubmed or parsed from bibtex ''' errors = [] progress_bar = hub.progress_bar(target=len(records), title="Adding references to database") progress_bar.show() for i, record in enumerate(records): more_errors = self.add_reference(record, node, single_mode=False) errors.extend(more_errors) progress_bar.update(i + 1) self._db.commit() # hub.refresh_tree_item(node) # we need to refresh the tree in order to update the Imported pseudo-folder hub.clear_cache() hub.tree.refresh() if len(errors): hub.show_errors(errors) refs_imported = self.item_count('refs') - self.ref_count_before suffix = '' if refs_imported == 1 else 's' hub.set_status_bar('Imported %s reference%s' % (refs_imported, suffix))
def recycle_trash(self): ''' recover all items from the trash and stuff it into the Recycled folder. ''' refs_before = self.item_count('reflink') recycled_id = self.recycled_node[1] stmt = "select ref_id from refs where ref_id not in (select distinct(ref_id) from reflink)" ref_ids = self._db.execute(stmt).fetchvalues() if not len(ref_ids): return for ref_id in ref_ids: self._db.insert('reflink', dict(ref_id=ref_id, branch_id=recycled_id)) self._db.commit() hub.clear_cache() hub.tree.refresh() refs_recycled = self.item_count('reflink') - refs_before refs_suffix = '' if refs_recycled == 1 else 's' hub.set_status_bar('Recycled %s reference%s' % (refs_recycled, refs_suffix))
def erase_node(self, node=None): ''' completely erase a reference. In this case, we just delete from the refs table and let it propagate to reflink etc. Yes, it works from the command line. ''' if node is None: # invocation from menu will trigger this case node = hub.tree.focus_element() node_type, node_id, parent_id = node parent = self.get_parent_node(node) if node_type == hub.BRANCH: hub.show_errors('Cannot erase folders') return #stmt = "delete from refs where ref_id=(?)" #Well, why take this aggressive approach? Why not just leave it in the trashcan? #Let's do that instead. stmt = "delete from reflink where ref_id=(?)" self._db.execute(stmt, [node_id]) self._db.commit() hub.tree.set_focus(parent) hub.tree.add_to_history(parent) # does this make sense? I suppose so. hub.coredb.clear_cache() hub.tree.refresh() hub.set_status_bar('Moved one reference to trash')
def cite_selected_oo(self): ''' cite all currently selected references. ''' selected_refs = hub.get_selected_refs( ) # list of (ref__id, branch_id) tuples if len(selected_refs) == 0: hub.show_errors("No references selected") return seen = set() for ref_id, branch_id in selected_refs: if ref_id in seen: continue seen.add(ref_id) fake_node = (hub.REF, ref_id, branch_id) try: self.oo_cite(fake_node, status=False) except ConnectionError: hub.show_errors("No active Writer document found") return suffix = "" if len(seen) == 1 else "s" hub.set_status_bar('cited %s reference%s' % (len(seen), suffix))
def oo_cite(self, node=None, status=True): ''' insert a single reference into openoffice ''' if node is None: node = hub.tree.focus_element() assert hub.is_ref(node) raw_data = self.get_ref_dict(node) adapted = {} junk = "branches abstract selected pmid reftype_id purpose ref_id" for key, value in raw_data.items(): if key in junk: continue new_key = self.key_mapping.get(key, key.title()) adapted[new_key] = str(value) # pprint.pprint(adapted) try: self.insert_ref(adapted) except ConnectionError: hub.show_errors("No active Writer document found") if status: hub.set_status_bar('cited %s' % adapted['Identifier'])
def delete_node(self, node=None): ''' delete either a folder or a reference. In the case of folders, we rely on SQLite cascading to delete nested content. ''' refs_before = self.item_count('reflink') folders_before = self.item_count('branches') if node is None: # invocation from menu will trigger this case node = hub.tree.focus_element() parent = self.get_parent_node(node) node_type, node_id, parent_id = node if node_type == hub.BRANCH: if node_id in self.special_branch_ids: hub.show_errors('This folder is protected') return stmt = "delete from branches where branch_id=(?)" values = [node_id] else: stmt = "delete from reflink where ref_id=(?) and branch_id=(?)" values = [node_id, parent_id] self._db.execute(stmt, values) self._db.commit() hub.tree.set_focus(parent) hub.tree.add_to_history(parent) # does this make sense? I suppose so. hub.coredb.clear_cache() hub.tree.refresh() rdel = refs_before - self.item_count('reflink') fdel = folders_before - self.item_count('branches') joiner = " and " if fdel > 0 and rdel > 0 else "" if fdel > 0: if fdel == 1: fs = "1 folder" else: fs = "%s folders" % fdel else: fs = "" if rdel > 0: if rdel == 1: rs = "1 reference" else: rs = "%s references" % rdel else: rs = "" hub.set_status_bar('Deleted %s%s%s' % (fs, joiner, rs))
def write_export_records(self, output, file_name, batch): ''' write formatted records to file. backend for both bibtex and html ''' try: rv = writefile(file_name, output) except Exception as error: if not batch: hub.show_errors(str(error)) else: traceback.print_exc() else: # hub.show_info("File %s written" % file_name) if not batch: hub.set_status_bar("Output sent to %s" % rv)
def show_pdf(self, node=None): ''' try to show a pdf file. If not there, show error; if multiple files, show first one. if we get annoyed with this, we can always bolt on a menu later ''' viewer = config['preferences'].get('pdf_viewer', 'xdg-open') bibtexkey = self.bibtexkey_for_node(node) path = self.pdf_filepath(bibtexkey) if path is None: hub.show_errors('PDF file not found') return # prevent subprocess from messing up the screen ... hub.set_status_bar('Opening PDF ...') fnull = open(os.devnull, 'w') subprocess.Popen([viewer, path], stdout=fnull, stderr=fnull)
def empty_trash(self): ''' like the man sez. How do we proceed? No more folders, so therefore all we have to do is delete references no longer represented in reflink. ''' refs_before = self.item_count('refs') stmt = "delete from refs where ref_id not in (select distinct(ref_id) from reflink)" self._db.execute(stmt) self._db.commit() self.refresh_tree_item(self.trash_node) refs_deleted = refs_before - self.item_count('refs') refs_suffix = '' if refs_deleted == 1 else 's' hub.set_status_bar('Deleted %s reference%s' % (refs_deleted, refs_suffix))
def _mail_references(self, ref_ids): ''' shared back-end for mailing selected or current references ''' stmt = "select bibtexkey from refs where ref_id in (%s)" keys = self._db.execute_qmarks(stmt, [list(ref_ids)]).fetchvalues() # I guess we want to keep track of which PDF files were actually found. # so, we don't just filter paths = [(key, self.pdf_filepath(key)) for key in keys] attach_list = [] missing_list = [] for key, path in paths: if path is None: missing_list.append(key) else: attach_list.append(path) if not len(attach_list): hub.show_errors("No PDF files found for selected reference(s)") return hub.set_status_bar('composing email') cmd = ["xdg-email"] cmd.append('--subject "%s"' % config['email'].get('subject', 'PDF files')) body = config['email'].get('body', 'Please see attached') if len(missing_list): body += '. PDFs not found for: %s' % ", ".join(missing_list) cmd.append('--body "%s"' % body) for fn in attach_list: cmd.append('--attach "%s"' % str(fn)) cmd = ' '.join(cmd) os.system("%s > /dev/null 2> /dev/null" % cmd) hub.set_status_bar('')
def _empty_folder(self, folder_id): ''' used with at least two folders (recycled and recently added) ''' refs_before = self.item_count('reflink') stmt = "delete from reflink where branch_id = (?)" c = self._db.execute(stmt, [folder_id]) deleted = c.rowcount if deleted == 0: return self._db.commit() hub.clear_cache() hub.tree.refresh() refs_deleted = refs_before - self.item_count('reflink') if refs_deleted > 0: refs_suffix = '' if refs_deleted == 1 else 's' hub.set_status_bar('Deleted %s reference%s' % (refs_deleted, refs_suffix))
def setup(self): hub.set_status_bar("") super(ResetStatusMixin, self).setup()