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()
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()
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))