示例#1
0
    def open_db(self):
        '''
        acquire db file, or quit
        '''
        if not os.path.isfile(dbfile):
            mbib_dir = os.environ.get('mbib_dir', '')
            empty_db = os.path.join(mbib_dir, db_template)

            if os.path.isfile(empty_db):
                while True:
                    answer = input(
                        "Database file %s not found. Create? (y/n) " %
                        dbfile).lower()[:]
                    if answer in "yn":
                        break
                if answer == 'n':
                    raise SystemExit("No database - exiting")
                # copy empty database file to configured path
                shutil.copy(empty_db, dbfile)
            else:
                raise SystemExit("Can find neither %s nor %s" %
                                 (dbfile, empty_db))

        elif config['preferences'].getboolean('backup_db_file'):
            backup_db = "%s.bak" % dbfile

            if not os.path.exists(backup_db) or os.stat(
                    backup_db).st_mtime < os.stat(dbfile).st_mtime:
                shutil.copy(dbfile, backup_db)

        # at this point, the database should be in place
        hub.register('sqlite', SqliteDB(dbfile))
        hub.register('dbfile', dbfile)

        self._db = hub.sqlite
示例#2
0
class BranchEdit(dialog.SimpleEdit):
    '''
    we can keep this simple.
    '''
    title_prefix = "Rename folder"
    prompt = "New name:"
    label_width = len(prompt)

    def setup(self):
        self.__super.setup()
        self.node = hub.tree.focus_element()
        self.current_name, weg = hub.get_node_text(self.node)
        self.title = "%s '%s'" % (self.title_prefix, self.current_name)

    def prevalidate(self):
        '''
        make sure we are in the right kind of folder
        '''
        node = hub.tree.focus_element()
        return hub.is_branch(
            node) and node[1] not in hub.coredb.special_branch_ids

    def show_invalid(self):
        hub.show_errors('This folder is protected and cannot be renamed')

    def process(self):
        '''
        read out any changed data and send them off for processing.
        '''
        new_name = self.get_edit_text()

        if self.current_name != new_name:
            hub.update_branch(self.node, self.current_name, new_name)

    hub.register('branch_edit', lambda *a, **kw: BranchEdit(*a, **kw).show())
示例#3
0
class ConfirmFlatten(NodeConfirmation):
    outer_height = 13
    processor_name = "flatten_folder"
    branch_question = "Erase all nested sub-folders and move their references to folder '%s'?"

    hub.register('confirm_flatten',
                 lambda *a, **kw: ConfirmFlatten(*a, **kw).show())
示例#4
0
class ConfirmErase(NodeConfirmation):
    #outer_height = 13
    processor_name = "erase_node"
    ref_question = "Delete %s from ALL folders?"

    hub.register('confirm_erase',
                 lambda *a, **kw: ConfirmErase(*a, **kw).show())
示例#5
0
class ConfirmDeleteOthers(NodeConfirmation):
    processor_name = "delete_other_instances"
    ref_question = "Delete %s from all other folders?"
    branch_question = "Delete references in %s from all other folders?"

    hub.register('confirm_delete_others',
                 lambda *a, **kw: ConfirmDeleteOthers(*a, **kw).show())
示例#6
0
class ConfirmDelete(NodeConfirmation):
    processor_name = "delete_node"
    ref_question = "Delete %s from this folder?"
    branch_question = "Delete %s?"

    hub.register('confirm_delete',
                 lambda *a, **kw: ConfirmDelete(*a, **kw).show())
示例#7
0
class PubmedInput(MbibInput):
    title = "Import from Pubmed"
    prompt = "Paste pmids or give filename:"
    multiline = True
    processor_name = "import_pubmed"
    processor_args = dict(node="node", raw_info="edit_text")

    hub.register('pubmed_input', lambda *a: PubmedInput().show())
示例#8
0
class SelectedToBibtex(SelectedToHtml):
    '''
    shove selected references into an HTML file
    '''
    title = "Export selected references to BibTex"
    processor_name = "export_bibtex"
    extension = ".bib"

    hub.register('bibtex_selected', lambda *a: SelectedToBibtex().show())
示例#9
0
class PdfInput(CiteInput):
    '''
    shortcut for citing a reference by exact bibtexkey
    we use 'like', however, to make the search case-insensitive.
    '''
    title = "Show a PDF file"
    processor_name = "show_pdf_bibtexkey"

    hub.register('pdf_key_input', lambda *a: PdfInput().show())
示例#10
0
class CiteInput(MbibInput):
    '''
    shortcut for citing a reference by exact bibtexkey
    '''
    title = "Cite reference in OOo"
    prompt = "BibTeX key:"
    processor_name = "cite_by_key"
    processor_args = dict(bibtexkey="edit_text")

    hub.register('cite_key_input', lambda *a: CiteInput().show())
示例#11
0
class HtmlFileInput(MbibFileInput):
    '''
    just specify a folder name. There seems to be no file browser widget;
    we will simply use os.path.abspath to evaluate the string given here.
    '''
    title = "Export HTML file"
    prompt = "File name:"
    extension = '.html'
    processor_name = "export_html"

    hub.register('html_filename', lambda *a: HtmlFileInput().show())
示例#12
0
class SelectedToHtml(MbibFileInput):
    '''
    shove selected references into an HTML file
    '''
    title = "Export selected references to HTML"
    processor_name = "export_html"
    processor_args = dict(file_name="edit_text")
    extension = ".html"

    _initial_text = lambda self: "selected" + self.extension

    hub.register('html_selected', lambda *a: SelectedToHtml().show())
示例#13
0
class BibtexInput(PubmedInput):
    '''
    paste bibtex code for import
    '''
    title = "Import references from BibTex"
    prompt = "paste BibTex or give filename:"
    processor_name = "import_bibtex"

    outer_width = 70
    outer_height = 30

    hub.register('bibtex_input', lambda *a: BibtexInput().show())
示例#14
0
class BibFileInput(MbibFileInput):
    '''
    just specify a file name. There seems to be no file browser widget;
    we will simply use os.path.abspath to evaluate the string given here.

    We could of course use a tkinter dialog.
    '''
    title = "Export BibTex file"
    prompt = "File name:"
    extension = ".bib"
    processor_name = "export_bibtex"

    hub.register('bibtex_filename', lambda *a: BibFileInput().show())
示例#15
0
class EditSearch(SearchForm):
    def setup(self):
        self.__super.setup()

        stored = hub.saved_search()

        if stored is not None:
            self.stored_data = stored
            self.title = "Edit search"
        else:
            self.title = "New search (no stored search available)"

    hub.register('edit_search', lambda *a: EditSearch().show())
示例#16
0
class SearchForm(RefAdd):
    '''
    we again just need an empty form; the differences kick in only in downstream.

    I might prune the fields here a little - 'tis just too much, ain't it.
    '''
    title = "Search for references"

    sequence = """
               bibtexkey
               reftype
               purpose
               title
               keywords
               comment
               author
               journal
               year
               abstract
               pmid
               doi
               url
               volume
               number
               pages
               booktitle
               editor
               publisher
               """
    sequence = sequence.strip().split()
    label_width = max([len(s) for s in sequence])

    def setup(self):
        self.__super.setup()
        self.title = "New search"

    def prevalidate(self):
        '''
        search can be accessed from anywhere
        '''
        return True

    def process(self):
        '''
        read out any changed data and send them off for processing.
        '''
        hub.search_references(self.get_data())

    hub.register('new_search', lambda *a: SearchForm().show())
示例#17
0
    def __init__(self, dtree, *a, **kw):
        '''
        get hold of that blasted directory tree manually.

        also, export nicely wrapped methods to broker, so that they can also be
        invoked from within dialogs without much trouble.
        '''
        self._dtree = dtree
        self.current_focus_element = None
        self.last_mouse_press = -3600

        self.__super.__init__(*a, **kw)

        # let uth keep the nodes we visit in history.
        # if we do go back in history, let us put the nodes
        # to the 'right' into the future.
        #
        # visited nodes are the ones we actually do work on, such
        # as viewing details. Does this include viewing folders?
        self._history = []
        self._future = []

        for key in self.exposed.strip().split():
            hub.register(key, getattr(self, key))
示例#18
0
class BranchFilter(dialog.SimpleEdit):
    '''
    filter branches recursively. Let's see how well that works ...

    I guess the idea is to filter all branches, top to bottom,
    that match the searched for phrase at any level? Show all
    precursors and descendants of each matching folder?

    Also, how do we deactivate this again?
    '''
    title = "Filter folders by name"
    prompt = "Search string: "

    def process(self):
        hub.filter_folders(self.get_edit_text())

    hub.register('filter_folders_dialog',
                 lambda *a, **kw: BranchFilter(*a, **kw).show())
示例#19
0
        w = max([len(mc[1]) for mc in [_f for _f in self.menu_choices if _f]] +
                [len(self.title)])
        self.outer_width = w + 14  # need enough space for shortcuts

    def process_choice(self, button, value):
        '''
        just hand it off to the hub.
        '''
        self.dismiss()

        if value:
            hub.process_action(value)


hub.register('show_selection_menu', lambda *a: SelectionMenu().show())


class BibMenu(ResetStatusMixin, dialog.Menu):
    '''
    well, I can see this growing quickly - with special cases for files, folders, and special folders ...
    '''
    # outer_height = 12 this is dynamically determined in .setup
    outer_width = 60

    # context menus differ for refs and folders, as well as by special folders.
    # the applicable menu is configured using nested dicts. None inserts a menu
    # separator.
    # We try to keep things consistent by defining some standard items first.

    _items = dict(
示例#20
0
        # finally, insert all references directly into parent, omitting duplicates
        remaining = set(nested_references) - set(direct_references)
        for ref in remaining:
            self._db.insert('reflink',
                            dict(ref_id=ref, branch_id=node_id, selected=0))

        # finish up
        self._db.commit()
        hub.clear_cache()
        hub.tree.refresh()


# we should expose some methods globally, to make menu responses easier.
_db = RefDb()

hub.register('coredb', _db)

_export = '''
          bibtexkey_for_node
          clear_cache
          extend_refs
          filter_folders
          flatten_folder
          get_branch_title
          get_child_nodes
          get_menu_keys
          get_named_node
          get_node_display_info
          get_node_text
          get_nodes_above
          get_parent_node
示例#21
0
#!/usr/bin/env python3
import os

batch_arg = os.getenv('mbib_batch')

# print("batch_arg", batch_arg)

if batch_arg is None:
    from bibapp import BibApp
    from hub import hub
    hub.is_batch = False
    _app = BibApp()
    hub.register('app', _app)
    hub.register('tree', _app.tree)
    hub.register('exit', _app.exit)
    hub.app()
else:
    from batchmode import BatchMode
    BatchMode(batch_arg)()


示例#22
0
            key, tpl = thing
            action, help_text = tpl
            self.set_widget(key, urwid.Text(help_text))

            if i + 1 < len(actions):
                self.add_divider()

    def exit_buttons(self):
        '''
        hook for creating dialog exit buttons.
        again, we need to figure out how to get hold of values.
        '''
        return [("OK", "ok")]


hub.register('show_help', lambda *args: HelpDialog().show())


class ErrorDialog(dialog.MessageBox):
    '''
    just pass a list of errors and display them. Why do I have this here, under help?

    Also, this isn't so great - it can easily overflow, and the we can't scroll. We
    should rather be adding widgets to the body. Well, let's wait an see. show_errors
    does take a 'height' argument that can be adjusted when needed.
    '''
    title = 'Error'
    message_style = 'error'
    outer_height = 10

示例#23
0
class DoiInput(PubmedInput):
    title = "Import from DOI"
    prompt = "Paste DOIs or give filename:"
    processor_name = "import_doi"

    hub.register('doi_input', lambda *a: DoiInput().show())