diff -Nru goobook-3.4/CHANGES.rst goobook-3.5/CHANGES.rst --- goobook-3.4/CHANGES.rst 2019-09-10 06:21:09.000000000 +0000 +++ goobook-3.5/CHANGES.rst 2020-09-07 14:18:07.000000000 +0000 @@ -1,6 +1,24 @@ CHANGES ======= +3.5 2020-09-07 +-------------- +* Issue 87: Adjustments to how authenticate is used and documented, removed embedded client_id and secret + Added documentation for getting a client_id and secret. + Deprecated "client_secret_filename" in config. +* Issue 82: Feature request: Option to add phone number when creating new contact +* Updated dependencies. +* Issue 89: Support XDG Spec, files located in the old locations is still used if + they exists but XDG locations are preferred. + + ex. + + - $XDG_CONFIG_HOME/goobookrc + - $XDG_CACHE_HOME/goobook_cache + - $XDG_DATA_HOME/goobook_auth.json + +* Issue 75: Added unauthenticate command. + 3.4 2019-09-10 -------------- * Issue 82: Cannot add contacts anymore diff -Nru goobook-3.4/debian/changelog goobook-3.5/debian/changelog --- goobook-3.4/debian/changelog 2019-10-02 11:00:26.000000000 +0000 +++ goobook-3.5/debian/changelog 2020-10-08 18:31:39.000000000 +0000 @@ -1,3 +1,18 @@ +goobook (3.5-2) unstable; urgency=medium + + * Use pyxdg instead of xdg which is not available on Debian. + Thanks to Matthew Moore for reporting this (Closes: #971852) + + -- Ilias Tsitsimpis Thu, 08 Oct 2020 21:31:39 +0300 + +goobook (3.5-1) unstable; urgency=low + + * New upstream release + * Use the debhelper-compat build-dependency and remove d/compat + * Bump Standards-Version to 4.5.0 + + -- Ilias Tsitsimpis Wed, 16 Sep 2020 11:07:33 +0300 + goobook (3.4-1) unstable; urgency=low * New upstream release diff -Nru goobook-3.4/debian/compat goobook-3.5/debian/compat --- goobook-3.4/debian/compat 2019-01-08 14:54:41.000000000 +0000 +++ goobook-3.5/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -12 diff -Nru goobook-3.4/debian/control goobook-3.5/debian/control --- goobook-3.4/debian/control 2019-10-02 11:00:06.000000000 +0000 +++ goobook-3.5/debian/control 2020-10-08 18:31:39.000000000 +0000 @@ -4,12 +4,12 @@ Maintainer: Ilias Tsitsimpis Rules-Requires-Root: no Build-Depends: - debhelper (>= 12), + debhelper-compat (= 12), dh-python, python3-all, python3-setuptools, python3-docutils, -Standards-Version: 4.4.1 +Standards-Version: 4.5.0 Vcs-Browser: https://salsa.debian.org/debian/goobook Vcs-Git: https://salsa.debian.org/debian/goobook.git Homepage: https://pypi.python.org/pypi/goobook @@ -22,6 +22,7 @@ python3-googleapi (>= 1.6.4), python3-simplejson, python3-oauth2client, + python3-xdg, Enhances: mutt Description: command-line interface to Google contacts diff -Nru goobook-3.4/debian/patches/series goobook-3.5/debian/patches/series --- goobook-3.4/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ goobook-3.5/debian/patches/series 2020-10-08 18:31:39.000000000 +0000 @@ -0,0 +1 @@ +Use-pyxdg-instead-of-xdg-which-is-not-available-on-Debian.patch diff -Nru goobook-3.4/debian/patches/Use-pyxdg-instead-of-xdg-which-is-not-available-on-Debian.patch goobook-3.5/debian/patches/Use-pyxdg-instead-of-xdg-which-is-not-available-on-Debian.patch --- goobook-3.4/debian/patches/Use-pyxdg-instead-of-xdg-which-is-not-available-on-Debian.patch 1970-01-01 00:00:00.000000000 +0000 +++ goobook-3.5/debian/patches/Use-pyxdg-instead-of-xdg-which-is-not-available-on-Debian.patch 2020-10-08 18:31:39.000000000 +0000 @@ -0,0 +1,97 @@ +From: Ilias Tsitsimpis +Date: Thu, 8 Oct 2020 21:30:01 +0300 +Subject: Use pyxdg instead of xdg which is not available on Debian + +--- + goobook/config.py | 23 +++++++++++++++-------- + setup.py | 1 + + 2 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/goobook/config.py b/goobook/config.py +index 8225c7b..7cd6253 100644 +--- a/goobook/config.py ++++ b/goobook/config.py +@@ -10,7 +10,8 @@ import configparser + import logging + + import oauth2client.client +-import xdg ++from xdg.BaseDirectory import (xdg_cache_home, xdg_config_home, ++ xdg_config_dirs, xdg_data_dirs, xdg_data_home) + + from goobook.storage import Storage + +@@ -43,6 +44,12 @@ TEMPLATE = '''\ + ;default_group: + ''' + ++def topath(x): ++ if isinstance(x, list): ++ return [pathlib.Path(_x) for _x in x] ++ else: ++ return pathlib.Path(x) ++ + + def read_config(config_file=None): + """Reads the ~/.goobookrc and any authentication data. +@@ -61,8 +68,8 @@ def read_config(config_file=None): + if config_file: # config file explicitly given on the commandline + config_file = os.path.expanduser(config_file) + else: # search for goobookrc in XDG dirs and homedir +- config_files = [dir_ / "goobookrc" for dir_ in [xdg.XDG_CONFIG_HOME] + +- xdg.XDG_CONFIG_DIRS] + [LEGACY_CONFIG_FILE] ++ config_files = [dir_ / "goobookrc" for dir_ in [topath(xdg_config_home)] + ++ topath(xdg_config_dirs)] + [LEGACY_CONFIG_FILE] + log.debug("config file search path: %s", config_files) + for config_file_ in config_files: + if config_file_.exists(): +@@ -93,7 +100,7 @@ def read_config(config_file=None): + if config.cache_filename: # If explicitly specified in config file + config.cache_filename = realpath(expanduser(config.cache_filename)) + else: # search for goobook_cache in XDG dirs and homedir +- cache_files = [xdg.XDG_CACHE_HOME / "goobook_cache", LEGACY_CACHE_FILE] ++ cache_files = [topath(xdg_cache_home) / "goobook_cache", LEGACY_CACHE_FILE] + log.debug("cache file search path: %s", cache_files) + for cache_file in cache_files: + cache_file = cache_file.resolve() +@@ -101,7 +108,7 @@ def read_config(config_file=None): + log.debug("found cache file: %s", cache_file) + break + else: # If there is none, create in XDG_CACHE_HOME +- cache_file = xdg.XDG_CACHE_HOME / "goobook_cache" ++ cache_file = topath(xdg_cache_home) / "goobook_cache" + log.debug("no cache file found, will use %s", cache_file) + config.cache_filename = str(cache_file) + +@@ -109,8 +116,8 @@ def read_config(config_file=None): + if config.oauth_db_filename: # If explicitly specified in config file + config.oauth_db_filename = realpath(expanduser(config.oauth_db_filename)) + else: # search for goobook_auth.json in XDG dirs and homedir +- auth_files = [dir_ / "goobook_auth.json" for dir_ in [xdg.XDG_DATA_HOME] + +- xdg.XDG_DATA_DIRS] + [LEGACY_AUTH_FILE] ++ auth_files = [dir_ / "goobook_auth.json" for dir_ in [topath(xdg_data_home)] + ++ topath(xdg_data_dirs)] + [LEGACY_AUTH_FILE] + log.debug("auth file search path: %s", auth_files) + for auth_file in auth_files: + auth_file = auth_file.resolve() +@@ -118,7 +125,7 @@ def read_config(config_file=None): + log.debug("found auth file: %s", auth_file) + break + else: # If there is none, create in XDG_DATA_HOME +- auth_file = xdg.XDG_DATA_HOME / "goobook_auth.json" ++ auth_file = topath(xdg_data_home) / "goobook_auth.json" + log.debug("no auth file found, will use %s", auth_file) + config.oauth_db_filename = str(auth_file) + +diff --git a/setup.py b/setup.py +index 3a40c51..7ed6149 100755 +--- a/setup.py ++++ b/setup.py +@@ -39,6 +39,7 @@ setuptools.setup( + 'google-api-python-client>=1.6.4', + 'simplejson>=2.1.0', + 'oauth2client>=1.5.0,<5.0.0dev', ++ 'pyxdg', + ], + extras_require={ + }, diff -Nru goobook-3.4/goobook/application.py goobook-3.5/goobook/application.py --- goobook-3.4/goobook/application.py 2018-10-29 08:34:33.000000000 +0000 +++ goobook-3.5/goobook/application.py 2020-09-03 19:22:22.000000000 +0000 @@ -8,7 +8,7 @@ import datetime import locale import logging -import os +import pathlib import json import sys @@ -16,7 +16,6 @@ import oauth2client.file import oauth2client.tools import pkg_resources -from pkg_resources import resource_filename import goobook.config from goobook.goobook import GooBook, Cache, GoogleContacts, parse_groups, parse_contacts @@ -24,9 +23,29 @@ log = logging.getLogger(__name__) # pylint: disable=invalid-name -CONFIG_FILE = '~/.goobookrc' SCOPES = 'https://www.google.com/m8/feeds' # read/write access to Contacts and Contact Groups +AUTHENTICATE_HELP_STRING = '''Google OAuth authentication. + +Before running goobook authenticate you need a client_id and a client_secret, get it like this: + +Go to https://developers.google.com/people/quickstart/python +and click "Enable the People API" +select a name (ex. GooBook) +select desktop application +save the client_id and client_secret to be used below:: + + $ goobook authenticate -- CLIENT_ID CLIENT_SECRET + +and follow the instructions. + +if it doesn't open a webbrowser use + +goobook authenticate --noauth_local_webserver -- CLIENT_ID CLIENT_SECRET + +If you get the page "This app isn't verified" select Advanced and the "Go to GooBook (unsafe)" at the bottom. +''' + def main(): locale.setlocale(locale.LC_TIME, '') # Use system configured locale @@ -41,7 +60,7 @@ help="Print version and exit") parser.add_argument('-d', '--debug', dest="log_level", action='store_const', const=logging.DEBUG, help='Output debug info (stderr).') - parser.set_defaults(config=CONFIG_FILE, log_level=logging.ERROR) + parser.set_defaults(log_level=logging.ERROR) subparsers = parser.add_subparsers() @@ -52,6 +71,8 @@ help='Name to use.') parser_add.add_argument('email', nargs='?', metavar='EMAIL', help='E-mail to use.') + parser_add.add_argument('phone', nargs='?', metavar='PHONE', + help='Phone number to use.') parser_add.set_defaults(func=do_add) parser_config_template = subparsers.add_parser('config-template', @@ -86,11 +107,19 @@ parser_reload.set_defaults(func=do_reload) parser_auth = subparsers.add_parser('authenticate', - description='Google OAuth authentication.', + description=AUTHENTICATE_HELP_STRING, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[oauth2client.tools.argparser]) + parser_auth.add_argument('client_id', metavar='CLIENT_ID', + help='Client ID') + parser_auth.add_argument('client_secret', metavar='CLIENT_SECRET', + help='Client secret') parser_auth.set_defaults(func=do_authenticate) + parser_unauth = subparsers.add_parser('unauthenticate', + description="Removed authentication data (logout).") + parser_unauth.set_defaults(func=do_unauthenticate) + args = parser.parse_args() logging.basicConfig(level=args.log_level) @@ -114,7 +143,7 @@ def do_add(config, args): goobk = GooBook(config) if args.name and args.email: - goobk.add_mail_contact(args.name, args.email) + goobk.add_mail_contact(args.name, args.email, args.phone) else: goobk.add_email_from(sys.stdin) goobk.cache.load(force_update=True) @@ -170,14 +199,18 @@ creds = config.creds if not creds or creds.invalid: - client_secret_filename = config.client_secret_filename - if not os.path.exists(client_secret_filename): - client_secret_filename = resource_filename(__name__, 'client_secret.json') - flow = oauth2client.client.flow_from_clientsecrets(client_secret_filename, SCOPES) + flow = oauth2client.client.OAuth2WebServerFlow(args.client_id, args.client_secret, SCOPES) creds = oauth2client.tools.run_flow(flow, store, args) else: print('You are already authenticated.') +def do_unauthenticate(config, _args): + oauth_db = pathlib.Path(config.oauth_db_filename) + if oauth_db.exists(): + oauth_db.unlink() + print("deleted", oauth_db) + + if __name__ == '__main__': main() diff -Nru goobook-3.4/goobook/client_secret.json goobook-3.5/goobook/client_secret.json --- goobook-3.4/goobook/client_secret.json 2015-06-02 20:21:49.000000000 +0000 +++ goobook-3.5/goobook/client_secret.json 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -{"installed":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","client_secret":"iB-6KmYDQotAf2nd_fPoY86A","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","oob"],"client_x509_cert_url":"","client_id":"500614897810-h9eub98go537fqplj9k59ouip21j8a1e.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}} \ No newline at end of file diff -Nru goobook-3.4/goobook/config.py goobook-3.5/goobook/config.py --- goobook-3.4/goobook/config.py 2018-10-29 08:34:33.000000000 +0000 +++ goobook-3.5/goobook/config.py 2020-09-03 19:28:01.000000000 +0000 @@ -3,15 +3,21 @@ # author: Christer Sjöholm -- hcs AT furuvik DOT net import os +import pathlib +import sys from os.path import realpath, expanduser import configparser import logging import oauth2client.client +import xdg from goobook.storage import Storage log = logging.getLogger(__name__) # pylint: disable=invalid-name +LEGACY_CONFIG_FILE = pathlib.Path('~/.goobookrc').expanduser() +LEGACY_AUTH_FILE = pathlib.Path('~/.goobook_auth.json').expanduser() +LEGACY_CACHE_FILE = pathlib.Path('~/.goobook_cache').expanduser() TEMPLATE = '''\ # Use this template to create your ~/.goobookrc @@ -19,17 +25,14 @@ # "#" or ";" at the start of a line makes it a comment. [DEFAULT] -# The following are optional, defaults are shown +# The following are optional, defaults are shown when not other specified. # This file is written by the oauth library, and should be kept secure, # it's like a password to your google contacts. +# default is to place it in the XDG_DATA_HOME ;oauth_db_filename: ~/.goobook_auth.json -# The client secret file is not really secret, -# usually the bundled default secret is used. -;client_secret_filename: ~/.goobook_client_secret.json - -;cache_filename: ~/.goobook_cache +;cache_filename: ~/.goobook_cache # default is in the XDG_CACHE_HOME ;cache_expiry_hours: 24 ;filter_groupless_contacts: yes @@ -41,34 +44,87 @@ ''' -def read_config(config_file): - """Reads the ~/.goobookrc and any authentication data +def read_config(config_file=None): + """Reads the ~/.goobookrc and any authentication data. returns the configuration as a dictionary. """ config = Storage({ # Default values - 'cache_filename': '~/.goobook_cache', - 'oauth_db_filename': '~/.goobook_auth.json', - 'client_secret_filename': '~/.goobook_client_secret.json', + 'cache_filename': None, + 'oauth_db_filename': None, 'cache_expiry_hours': '24', 'filter_groupless_contacts': True, 'default_group': ''}) - config_file = os.path.expanduser(config_file) - parser = _get_config(config_file) + + # Search for config file to use + if config_file: # config file explicitly given on the commandline + config_file = os.path.expanduser(config_file) + else: # search for goobookrc in XDG dirs and homedir + config_files = [dir_ / "goobookrc" for dir_ in [xdg.XDG_CONFIG_HOME] + + xdg.XDG_CONFIG_DIRS] + [LEGACY_CONFIG_FILE] + log.debug("config file search path: %s", config_files) + for config_file_ in config_files: + if config_file_.exists(): + config_file = str(config_file_) + log.debug("found config file: %s", config_file) + break + else: + log.debug("no config file found") + config_file = None + # else: # .goobookrc in home directory + # config_file = os.path.expanduser(CONFIG_FILE) + + if config_file: + parser = _get_config(config_file) + else: + parser = None + if parser: config.get_dict().update(dict(parser.items('DEFAULT', raw=True))) # Handle not string fields if parser.has_option('DEFAULT', 'filter_groupless_contacts'): config.filter_groupless_contacts = parser.getboolean('DEFAULT', 'filter_groupless_contacts') - # Ensure paths are fully expanded - config.cache_filename = realpath(expanduser(config.cache_filename)) - config.client_secret_filename = realpath(expanduser(config.client_secret_filename)) - config.oauth_db_filename = realpath(expanduser(config.oauth_db_filename)) + if "client_secret_filename" in config: + print("WARNING: setting client_secret_filename in {} is deprecated".format(config_file), file=sys.stderr) + + # Search for cache file to use + if config.cache_filename: # If explicitly specified in config file + config.cache_filename = realpath(expanduser(config.cache_filename)) + else: # search for goobook_cache in XDG dirs and homedir + cache_files = [xdg.XDG_CACHE_HOME / "goobook_cache", LEGACY_CACHE_FILE] + log.debug("cache file search path: %s", cache_files) + for cache_file in cache_files: + cache_file = cache_file.resolve() + if cache_file.exists(): + log.debug("found cache file: %s", cache_file) + break + else: # If there is none, create in XDG_CACHE_HOME + cache_file = xdg.XDG_CACHE_HOME / "goobook_cache" + log.debug("no cache file found, will use %s", cache_file) + config.cache_filename = str(cache_file) + + # Search for auth file to use + if config.oauth_db_filename: # If explicitly specified in config file + config.oauth_db_filename = realpath(expanduser(config.oauth_db_filename)) + else: # search for goobook_auth.json in XDG dirs and homedir + auth_files = [dir_ / "goobook_auth.json" for dir_ in [xdg.XDG_DATA_HOME] + + xdg.XDG_DATA_DIRS] + [LEGACY_AUTH_FILE] + log.debug("auth file search path: %s", auth_files) + for auth_file in auth_files: + auth_file = auth_file.resolve() + if auth_file.exists(): + log.debug("found auth file: %s", auth_file) + break + else: # If there is none, create in XDG_DATA_HOME + auth_file = xdg.XDG_DATA_HOME / "goobook_auth.json" + log.debug("no auth file found, will use %s", auth_file) + config.oauth_db_filename = str(auth_file) config.store = oauth2client.file.Storage(config.oauth_db_filename) - config.creds = config.store.get() + + config.creds = config.store.get() if auth_file.exists() else None log.debug(config) return config diff -Nru goobook-3.4/goobook/goobook.py goobook-3.5/goobook/goobook.py --- goobook-3.4/goobook/goobook.py 2019-09-10 06:03:56.000000000 +0000 +++ goobook-3.5/goobook/goobook.py 2020-08-31 19:51:40.000000000 +0000 @@ -31,7 +31,7 @@ import time import httplib2 -from apiclient.discovery import build +from googleapiclient.discovery import build from goobook.storage import Storage, storageify, unstorageify @@ -43,7 +43,7 @@ class GooBook(): - """Application logic + """Application logic. This class can't be used as a library as it looks now, it uses sys.stdin print and sys.exit(). @@ -55,7 +55,7 @@ self.cache.load() def query(self, query, simple=False): - """Do the query, and print it out in + """Do the query, and print it out in specified format. simple=False is the mutt format simple format is: @@ -180,16 +180,17 @@ if group in contact.groups: yield contact - def add_mail_contact(self, name, mailaddr): + def add_mail_contact(self, name, mailaddr, phone=None): contact = { 'names': [{'givenName': name}], 'emailAddresses': [{'value': mailaddr}], + 'phoneNumbers': [{'value': phone}], } gcont = GoogleContacts(self.__config) - log.debug('Going to create contact name: %s email: %s', name, mailaddr) + log.debug('Going to create contact name: %s email: %s phone: %s', name, mailaddr, phone) gcont.create_contact(contact) - log.info('Created contact name: %s email: %s', name, mailaddr) + log.info('Created contact name: %s email: %s %s', name, mailaddr, phone) def add_email_from(self, lines): """Add an address from From: field of a mail. @@ -197,6 +198,7 @@ This assumes a single mail file is supplied through. Args: + ---- lines: A generator of lines, usually a open file. """ @@ -232,9 +234,10 @@ self.groups = None # list of Storage def load(self, force_update=False): - """Load the cached addressbook feed, or fetch it (again) if it is old or missing or invalid or anything + """Load the cached addressbook feed, or fetch it (again) if it is old or missing or invalid or anything. Args: + ---- force_update: force update of cache """ @@ -270,7 +273,7 @@ self.save() def save(self): - """Pickle the addressbook and a timestamp""" + """Pickle the addressbook and a timestamp.""" if self.contacts: # never write a empty addressbook cache = {'contacts': unstorageify(self.contacts), 'groups': unstorageify(self.groups), @@ -387,7 +390,8 @@ x__xgafv=None, pageToken=None, sortOrder=None, - personFields='names,nicknames,emailAddresses,memberships,phoneNumbers,birthdays,imClients,organizations,addresses', + personFields=('names,nicknames,emailAddresses,memberships,' + 'phoneNumbers,birthdays,imClients,organizations,addresses'), requestSyncToken=None, syncToken=None, requestMask_includeField=None) diff -Nru goobook-3.4/goobook.1.rst goobook-3.5/goobook.1.rst --- goobook-3.4/goobook.1.rst 2018-10-29 08:34:33.000000000 +0000 +++ goobook-3.5/goobook.1.rst 2020-09-03 19:22:22.000000000 +0000 @@ -8,7 +8,7 @@ :Author: This manual page has been written by Dariusz Dwornikowski and Christer Sjöholm -:Date: 2018-09-22 +:Date: 2020-09-02 :Manual section: 1 :Manual group: User Manuals @@ -53,11 +53,11 @@ authenticate Allow goobook to access your Google contacts using OAuth2. -add - Read an email address from stdin and add the From: address to your Google contacts. +add [NAME] [EMAIL] [PHONE] + Add a new Google contact. If NAME and EMAIL is not specified, read an email address from stdin and add the From: address to your Google contacts. config-template - Create a config template of **~/.goobookrc**. + Display a config template of that can be written to **~/.config/goobookrc**. dump_contacts dump all your contacts to XML (stdout). @@ -82,17 +82,17 @@ ------------- | For most users it will be enough to run: | -| **goobook** authenticate +| **goobook** authenticate --help +| +| and follow the instructions | To have access to more advanced options, you can generate a config file by doing: | -| **goobook** config-template > ~/.goobookrc +| **goobook** config-template > ~/.config/goobookrc An example config can look like this:: [DEFAULT] - oauth_db_filename: ~/.goobook_auth.json - cache_filename: ~/.goobook_cache cache_expiry_hours: 24 diff -Nru goobook-3.4/goobook.egg-info/PKG-INFO goobook-3.5/goobook.egg-info/PKG-INFO --- goobook-3.4/goobook.egg-info/PKG-INFO 2019-09-10 06:22:26.000000000 +0000 +++ goobook-3.5/goobook.egg-info/PKG-INFO 2020-09-07 14:21:34.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: goobook -Version: 3.4 +Version: 3.5 Summary: Search your google contacts from the command-line or mutt. Home-page: http://gitlab.com/goobook/goobook Author: Christer Sjöholm @@ -21,6 +21,8 @@ the command-line and from MUAs such as Mutt. It can be used from Mutt the same way as abook. + .. NOTE:: GooBook is looking for a new maintainer see https://gitlab.com/goobook/goobook/-/issues/90 + Installation Instructions ========================= @@ -85,32 +87,56 @@ Configuration ============= - For most users it will be enough to to run:: + First you need to authenticate yourself: - $ goobook authenticate + - Go to https://developers.google.com/people/quickstart/python + - and click "Enable the People API" + - select a name (ex. GooBook) + - select desktop app and create + - save the client_id and client_secret to be used below + + run:: + + $ goobook authenticate -- CLIENT_ID CLIENT_SECRET + + and follow the instructions, this part is web based. + + + If the procedure above to get client_id and secret stops working this is an alternative way to do it: + + - Go to the Google developer console https://console.developers.google.com/ + - Create a new project (drop down at the top of the screen) (you are free to use an existing one if you so prefer) + - Select the newly created project + - Go to OAuth consent screen from sidebar + - Select the interal user type if you can but most will only be able to select external. + - On next screen give it a name (ex. GooBook) + - select Add scope, click manually paste and write "https://www.googleapis.com/auth/contacts" inte the lower text box. + - and hit hit add and then save + - Go to Credentials from sidebar + - Click Create Credentials from top, then OAuth Client ID in the dropdown + - Choose Desktop app, enter any name you want, and hit create + - save the client_id and client_secret to be used with goobook authenticate - and follow the instructions. To get access too more settings you can create a configuration file:: - goobook config-template > ~/.goobookrc + goobook config-template > ~/.config/goobookrc It will look like this:: + # Use this template to create your ~/.goobookrc # "#" or ";" at the start of a line makes it a comment. + [DEFAULT] - # The following are optional, defaults are shown + # The following are optional, defaults are shown when not other specified. # This file is written by the oauth library, and should be kept secure, # it's like a password to your google contacts. + # default is to place it in the XDG_DATA_HOME ;oauth_db_filename: ~/.goobook_auth.json - # The client secret file is not really secret, - # usually the bundled default secret is used. - ;client_secret_filename: ~/.goobook_client_secret.json - - ;cache_filename: ~/.goobook_cache + ;cache_filename: ~/.goobook_cache # default is in the XDG_CACHE_HOME ;cache_expiry_hours: 24 ;filter_groupless_contacts: yes @@ -121,6 +147,19 @@ ;default_group: + Files + ----- + + GooBook is using three files, the optional config file that can be placed in the + XDG_CONFIG_HOME (~/.config/goobookrc) or in the home directory (~/.goobookrc). + + The authentication file that is created by running goobook authenticate + in XDG_DATA_HOME (~/.local/share/goobook_auth.json) but can also be placed + in the home directory (~/.goobook_auth.json). + + The contacts cache file that is created in XDG_CACHE_HOME (~/.cache/goobook_cache) + but can also be placed in the home directory (~/.goobook_cache). + Proxy settings -------------- @@ -182,6 +221,24 @@ CHANGES ======= + 3.5 2020-09-07 + -------------- + * Issue 87: Adjustments to how authenticate is used and documented, removed embedded client_id and secret + Added documentation for getting a client_id and secret. + Deprecated "client_secret_filename" in config. + * Issue 82: Feature request: Option to add phone number when creating new contact + * Updated dependencies. + * Issue 89: Support XDG Spec, files located in the old locations is still used if + they exists but XDG locations are preferred. + + ex. + + - $XDG_CONFIG_HOME/goobookrc + - $XDG_CACHE_HOME/goobook_cache + - $XDG_DATA_HOME/goobook_auth.json + + * Issue 75: Added unauthenticate command. + 3.4 2019-09-10 -------------- * Issue 82: Cannot add contacts anymore @@ -395,7 +452,8 @@ Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Intended Audience :: End Users/Desktop -Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) Classifier: Topic :: Communications :: Email :: Address Book Description-Content-Type: text/x-rst diff -Nru goobook-3.4/goobook.egg-info/SOURCES.txt goobook-3.5/goobook.egg-info/SOURCES.txt --- goobook-3.4/goobook.egg-info/SOURCES.txt 2019-09-10 06:22:26.000000000 +0000 +++ goobook-3.5/goobook.egg-info/SOURCES.txt 2020-09-07 14:21:34.000000000 +0000 @@ -10,7 +10,6 @@ setup.py goobook/__init__.py goobook/application.py -goobook/client_secret.json goobook/config.py goobook/goobook.py goobook/storage.py diff -Nru goobook-3.4/PKG-INFO goobook-3.5/PKG-INFO --- goobook-3.4/PKG-INFO 2019-09-10 06:22:26.000000000 +0000 +++ goobook-3.5/PKG-INFO 2020-09-07 14:21:34.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: goobook -Version: 3.4 +Version: 3.5 Summary: Search your google contacts from the command-line or mutt. Home-page: http://gitlab.com/goobook/goobook Author: Christer Sjöholm @@ -21,6 +21,8 @@ the command-line and from MUAs such as Mutt. It can be used from Mutt the same way as abook. + .. NOTE:: GooBook is looking for a new maintainer see https://gitlab.com/goobook/goobook/-/issues/90 + Installation Instructions ========================= @@ -85,32 +87,56 @@ Configuration ============= - For most users it will be enough to to run:: + First you need to authenticate yourself: - $ goobook authenticate + - Go to https://developers.google.com/people/quickstart/python + - and click "Enable the People API" + - select a name (ex. GooBook) + - select desktop app and create + - save the client_id and client_secret to be used below + + run:: + + $ goobook authenticate -- CLIENT_ID CLIENT_SECRET + + and follow the instructions, this part is web based. + + + If the procedure above to get client_id and secret stops working this is an alternative way to do it: + + - Go to the Google developer console https://console.developers.google.com/ + - Create a new project (drop down at the top of the screen) (you are free to use an existing one if you so prefer) + - Select the newly created project + - Go to OAuth consent screen from sidebar + - Select the interal user type if you can but most will only be able to select external. + - On next screen give it a name (ex. GooBook) + - select Add scope, click manually paste and write "https://www.googleapis.com/auth/contacts" inte the lower text box. + - and hit hit add and then save + - Go to Credentials from sidebar + - Click Create Credentials from top, then OAuth Client ID in the dropdown + - Choose Desktop app, enter any name you want, and hit create + - save the client_id and client_secret to be used with goobook authenticate - and follow the instructions. To get access too more settings you can create a configuration file:: - goobook config-template > ~/.goobookrc + goobook config-template > ~/.config/goobookrc It will look like this:: + # Use this template to create your ~/.goobookrc # "#" or ";" at the start of a line makes it a comment. + [DEFAULT] - # The following are optional, defaults are shown + # The following are optional, defaults are shown when not other specified. # This file is written by the oauth library, and should be kept secure, # it's like a password to your google contacts. + # default is to place it in the XDG_DATA_HOME ;oauth_db_filename: ~/.goobook_auth.json - # The client secret file is not really secret, - # usually the bundled default secret is used. - ;client_secret_filename: ~/.goobook_client_secret.json - - ;cache_filename: ~/.goobook_cache + ;cache_filename: ~/.goobook_cache # default is in the XDG_CACHE_HOME ;cache_expiry_hours: 24 ;filter_groupless_contacts: yes @@ -121,6 +147,19 @@ ;default_group: + Files + ----- + + GooBook is using three files, the optional config file that can be placed in the + XDG_CONFIG_HOME (~/.config/goobookrc) or in the home directory (~/.goobookrc). + + The authentication file that is created by running goobook authenticate + in XDG_DATA_HOME (~/.local/share/goobook_auth.json) but can also be placed + in the home directory (~/.goobook_auth.json). + + The contacts cache file that is created in XDG_CACHE_HOME (~/.cache/goobook_cache) + but can also be placed in the home directory (~/.goobook_cache). + Proxy settings -------------- @@ -182,6 +221,24 @@ CHANGES ======= + 3.5 2020-09-07 + -------------- + * Issue 87: Adjustments to how authenticate is used and documented, removed embedded client_id and secret + Added documentation for getting a client_id and secret. + Deprecated "client_secret_filename" in config. + * Issue 82: Feature request: Option to add phone number when creating new contact + * Updated dependencies. + * Issue 89: Support XDG Spec, files located in the old locations is still used if + they exists but XDG locations are preferred. + + ex. + + - $XDG_CONFIG_HOME/goobookrc + - $XDG_CACHE_HOME/goobook_cache + - $XDG_DATA_HOME/goobook_auth.json + + * Issue 75: Added unauthenticate command. + 3.4 2019-09-10 -------------- * Issue 82: Cannot add contacts anymore @@ -395,7 +452,8 @@ Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Intended Audience :: End Users/Desktop -Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) Classifier: Topic :: Communications :: Email :: Address Book Description-Content-Type: text/x-rst diff -Nru goobook-3.4/README.rst goobook-3.5/README.rst --- goobook-3.4/README.rst 2018-10-29 08:34:33.000000000 +0000 +++ goobook-3.5/README.rst 2020-09-03 19:22:22.000000000 +0000 @@ -12,6 +12,8 @@ the command-line and from MUAs such as Mutt. It can be used from Mutt the same way as abook. +.. NOTE:: GooBook is looking for a new maintainer see https://gitlab.com/goobook/goobook/-/issues/90 + Installation Instructions ========================= @@ -76,32 +78,56 @@ Configuration ============= -For most users it will be enough to to run:: +First you need to authenticate yourself: - $ goobook authenticate +- Go to https://developers.google.com/people/quickstart/python +- and click "Enable the People API" +- select a name (ex. GooBook) +- select desktop app and create +- save the client_id and client_secret to be used below + +run:: + + $ goobook authenticate -- CLIENT_ID CLIENT_SECRET + +and follow the instructions, this part is web based. + + +If the procedure above to get client_id and secret stops working this is an alternative way to do it: + +- Go to the Google developer console https://console.developers.google.com/ +- Create a new project (drop down at the top of the screen) (you are free to use an existing one if you so prefer) +- Select the newly created project +- Go to OAuth consent screen from sidebar +- Select the interal user type if you can but most will only be able to select external. +- On next screen give it a name (ex. GooBook) +- select Add scope, click manually paste and write "https://www.googleapis.com/auth/contacts" inte the lower text box. +- and hit hit add and then save +- Go to Credentials from sidebar +- Click Create Credentials from top, then OAuth Client ID in the dropdown +- Choose Desktop app, enter any name you want, and hit create +- save the client_id and client_secret to be used with goobook authenticate -and follow the instructions. To get access too more settings you can create a configuration file:: - goobook config-template > ~/.goobookrc + goobook config-template > ~/.config/goobookrc It will look like this:: + # Use this template to create your ~/.goobookrc # "#" or ";" at the start of a line makes it a comment. + [DEFAULT] - # The following are optional, defaults are shown + # The following are optional, defaults are shown when not other specified. # This file is written by the oauth library, and should be kept secure, # it's like a password to your google contacts. + # default is to place it in the XDG_DATA_HOME ;oauth_db_filename: ~/.goobook_auth.json - # The client secret file is not really secret, - # usually the bundled default secret is used. - ;client_secret_filename: ~/.goobook_client_secret.json - - ;cache_filename: ~/.goobook_cache + ;cache_filename: ~/.goobook_cache # default is in the XDG_CACHE_HOME ;cache_expiry_hours: 24 ;filter_groupless_contacts: yes @@ -112,6 +138,19 @@ ;default_group: +Files +----- + +GooBook is using three files, the optional config file that can be placed in the +XDG_CONFIG_HOME (~/.config/goobookrc) or in the home directory (~/.goobookrc). + +The authentication file that is created by running goobook authenticate +in XDG_DATA_HOME (~/.local/share/goobook_auth.json) but can also be placed +in the home directory (~/.goobook_auth.json). + +The contacts cache file that is created in XDG_CACHE_HOME (~/.cache/goobook_cache) +but can also be placed in the home directory (~/.goobook_cache). + Proxy settings -------------- diff -Nru goobook-3.4/setup.py goobook-3.5/setup.py --- goobook-3.4/setup.py 2019-09-10 06:21:34.000000000 +0000 +++ goobook-3.5/setup.py 2020-09-03 19:33:42.000000000 +0000 @@ -12,7 +12,7 @@ setuptools.setup( name='goobook', - version='3.4', + version='3.5', description='Search your google contacts from the command-line or mutt.', long_description=README + '\n\n' + NEWS, long_description_content_type="text/x-rst", @@ -28,8 +28,9 @@ Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 Intended Audience :: End Users/Desktop - License :: OSI Approved :: GNU General Public License (GPL) + License :: OSI Approved :: GNU General Public License v3 (GPLv3) Topic :: Communications :: Email :: Address Book """.splitlines() if f.strip()], keywords='abook mutt e-mail gmail google address-book',