Exemplo n.º 1
0
    def __init__(self, api_key=None, library_id=None, library_type='user'):
        """ Service class for communicating with the Zotero API.

        This is mainly a thin wrapper around :py:class:`pyzotero.zotero.Zotero`
        that handles things like transparent HTML<->[edit-formt] conversion.

        :param api_key:     API key for the Zotero API, will be loaded from
                            the configuration if not specified
        :param library_id:  Zotero library ID the API key is valid for, will
                            be loaded from the configuration if not specified
        :param library_type: Type of the library, can be 'user' or 'group'
        """
        self._logger = logging.getLogger()
        idx_path = os.path.join(click.get_app_dir(APP_NAME), 'index.sqlite')
        self.config = load_config()
        self.note_format = self.config['zotcli.note_format']
        self.storage_dir = self.config.get('zotcli.storage_dir')

        api_key = api_key or self.config.get('zotcli.api_key')
        library_id = library_id or self.config.get('zotcli.library_id')

        if not api_key or not library_id:
            raise ValueError(
                "Please set your API key and library ID by running "
                "`zotcli configure` or pass them as command-line options.")
        self._zot = Zotero(library_id=library_id, api_key=api_key,
                           library_type=library_type)
        self._index = SearchIndex(idx_path)
        sync_interval = self.config.get('zotcli.sync_interval', 300)
        since_last_sync = int(time.time()) - self._index.last_modified
        if since_last_sync >= int(sync_interval):
            self._logger.info("{} seconds since last sync, synchronizing."
                              .format(since_last_sync))
            self.synchronize()
Exemplo n.º 2
0
    def __init__(self, api_key=None, library_id=None, library_type='user'):
        """ Service class for communicating with the Zotero API.

        This is mainly a thin wrapper around :py:class:`pyzotero.zotero.Zotero`
        that handles things like transparent HTML<->[edit-formt] conversion.

        :param api_key:     API key for the Zotero API, will be loaded from
                            the configuration if not specified
        :param library_id:  Zotero library ID the API key is valid for, will
                            be loaded from the configuration if not specified
        :param library_type: Type of the library, can be 'user' or 'group'
        """
        self._logger = logging.getLogger()
        idx_path = os.path.join(click.get_app_dir(APP_NAME), 'index.sqlite')
        self.config = load_config()
        self.note_format = self.config['zotcli.note_format']
        self.storage_dir = self.config.get('zotcli.storage_dir')

        api_key = api_key or self.config.get('zotcli.api_key')
        library_id = library_id or self.config.get('zotcli.library_id')

        if not api_key or not library_id:
            raise ValueError(
                "Please set your API key and library ID by running "
                "`zotcli configure` or pass them as command-line options.")
        self._zot = Zotero(library_id=library_id, api_key=api_key,
                           library_type=library_type)
        self._index = SearchIndex(idx_path)
        sync_interval = self.config.get('zotcli.sync_interval', 300)
        since_last_sync = int(time.time()) - self._index.last_modified
        if since_last_sync >= int(sync_interval):
            self._logger.info("{} seconds since last sync, synchronizing."
                              .format(since_last_sync))
            self.synchronize()
Exemplo n.º 3
0
def configure(show):
    """ Perform initial setup. """
    if show:
        config = load_config()
        for key in config:
            print(f"{key:<25}:{config[key]}")
        return
    config = {'sync_interval': 300}
    generate_key = not click.confirm("Do you already have an API key for "
                                     "zotero-cli?")
    if generate_key:
        (config['api_key'],
         config['library_id']) = ZoteroBackend.create_api_key()
    else:
        config['api_key'] = click.prompt(
            "Please enter the API key for zotero-cli")
        config['library_id'] = click.prompt("Please enter your library ID")
    sync_method = select([("local", "Local Zotero storage"),
                          ("zotfile", 'Use ZotFile storage'),
                          ("zotcoud", "Use Zotero file cloud"),
                          ("webdav", "Use WebDAV storage")],
                         default=1,
                         required=True,
                         prompt="How do you want to access files for reading?")
    if sync_method == "local":
        storage_dirs = tuple(find_storage_directories())
        if storage_dirs:
            options = [(name, "{} ({})".format(click.style(name, fg="cyan"),
                                               path))
                       for name, path in storage_dirs]
            config['storage_dir'] = select(
                options,
                required=False,
                prompt="Please select a storage directory (-1 to enter "
                "manually)")
        if config.get('storage_dir') is None:
            click.echo(
                "Could not automatically locate a Zotero storage directory.")
            while True:
                storage_dir = click.prompt(
                    "Please enter the path to your Zotero storage directory",
                    default='')
                if not storage_dir:
                    storage_dir = None
                    break
                elif not os.path.exists(storage_dir):
                    click.echo("Directory does not exist!")
                elif not re.match(r'.*storage/?', storage_dir):
                    click.echo("Path must point to a `storage` directory!")
                else:
                    config['storage_dir'] = storage_dir
                    break
    elif sync_method == "zotfile":
        storage_dir = click.prompt(
            "Please enter the path to your Zotero storage directory",
            default='')
        config['storage_dir'] = storage_dir
    elif sync_method == "webdav":
        while True:
            if not config.get('webdav_path'):
                config['webdav_path'] = click.prompt(
                    "Please enter the WebDAV URL (without '/zotero'!)")
            if not config.get('webdav_user'):
                config['webdav_user'] = click.prompt(
                    "Please enter the WebDAV user name")
                config['webdav_pass'] = click.prompt(
                    "Please enter the WebDAV password")
            try:
                test_resp = requests.options(config['webdav_path'],
                                             auth=(config['webdav_user'],
                                                   config['webdav_pass']))
            except requests.ConnectionError:
                click.echo("Invalid WebDAV URL, could not reach server.")
                config['webdav_path'] = None
                continue
            if test_resp.status_code == 200:
                break
            elif test_resp.status_code == 404:
                click.echo("Invalid WebDAV path, does not exist.")
                config['webdav_path'] = None
            elif test_resp.status_code == 401:
                click.echo("Bad credentials.")
                config['webdav_user'] = None
            else:
                click.echo("Unknown error, please check your settings.")
                click.echo("Server response code was: {}".format(
                    test_resp.status_code))
                config['webdav_path'] = None
                config['webdav_user'] = None
    config['sync_method'] = sync_method

    markup_formats = pypandoc.get_pandoc_formats()[0]
    config['note_format'] = select(zip(markup_formats, markup_formats),
                                   default=markup_formats.index('markdown'),
                                   prompt="Select markup format for notes")
    save_config(config)
    zot = ZoteroBackend(config['api_key'], config['library_id'], 'user')
    click.echo("Initializing local index...")
    num_synced = zot.synchronize()
    click.echo("Synchronized {} items.".format(num_synced))