nncli

NextCloud Notes Command Line Interface
git clone git://git.danielmoch.com/nncli.git
Log | Files | Refs | LICENSE

commit d0e75dd9c33034f338ad4b4fc65bac6f81aff27e
parent 2b9a20dffeddbb02298838ca46b3da774a6a806d
Author: Samuel Walladge <swalladge@gmail.com>
Date:   Fri, 27 Nov 2015 12:18:55 +1030

added alternate host config option and support for custom config file

Diffstat:
Msimplenote_cli/config.py | 9+++++++--
Msimplenote_cli/notes_db.py | 3++-
Msimplenote_cli/simplenote.py | 30+++++++++++++++---------------
Msimplenote_cli/sncli.py | 36++++++++++++++++++++----------------
4 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/simplenote_cli/config.py b/simplenote_cli/config.py @@ -6,7 +6,7 @@ class Config: - def __init__(self): + def __init__(self, custom_file=None): self.home = os.path.abspath(os.path.expanduser('~')) defaults = \ { @@ -26,6 +26,7 @@ def __init__(self): 'cfg_max_logs' : '5', 'cfg_log_timeout' : '5', 'cfg_log_reversed' : 'yes', + 'cfg_sn_host' : 'simple-note.appspot.com', 'kb_help' : 'h', 'kb_quit' : 'q', @@ -119,7 +120,10 @@ def __init__(self): } cp = ConfigParser.SafeConfigParser(defaults) - self.configs_read = cp.read([os.path.join(self.home, '.snclirc')]) + if custom_file is not None: + self.configs_read = cp.read([custom_file]) + else: + self.configs_read = cp.read([os.path.join(self.home, '.snclirc')]) cfg_sec = 'sncli' @@ -131,6 +135,7 @@ def __init__(self): self.configs = collections.OrderedDict() self.configs['sn_username'] = [ cp.get(cfg_sec, 'cfg_sn_username', raw=True), 'Simplenote Username' ] self.configs['sn_password'] = [ cp.get(cfg_sec, 'cfg_sn_password', raw=True), 'Simplenote Password' ] + self.configs['sn_host'] = [ cp.get(cfg_sec, 'cfg_sn_host', raw=True), 'Simplenote server hostname' ] self.configs['db_path'] = [ cp.get(cfg_sec, 'cfg_db_path'), 'Note storage path' ] self.configs['search_tags'] = [ cp.get(cfg_sec, 'cfg_search_tags'), 'Search tags as well' ] self.configs['sort_mode'] = [ cp.get(cfg_sec, 'cfg_sort_mode'), 'Sort mode' ] diff --git a/simplenote_cli/notes_db.py b/simplenote_cli/notes_db.py @@ -59,7 +59,8 @@ def __init__(self, config, log, update_view): # initialise the simplenote instance we're going to use # this does not yet need network access self.simplenote = Simplenote(self.config.get_config('sn_username'), - self.config.get_config('sn_password')) + self.config.get_config('sn_password'), + self.config.get_config('sn_host')) # we'll use this to store which notes are currently being synced by # the background thread, so we don't add them anew if they're still diff --git a/simplenote_cli/simplenote.py b/simplenote_cli/simplenote.py @@ -30,9 +30,6 @@ # For Google AppEngine from django.utils import simplejson as json -AUTH_URL = 'https://simple-note.appspot.com/api/login' -DATA_URL = 'https://simple-note.appspot.com/api2/data' -INDX_URL = 'https://simple-note.appspot.com/api2/index?' NOTE_FETCH_LENGTH = 100 class SimplenoteLoginFailed(Exception): @@ -41,10 +38,13 @@ class SimplenoteLoginFailed(Exception): class Simplenote(object): """ Class for interacting with the simplenote web service """ - def __init__(self, username, password): + def __init__(self, username, password, host): """ object constructor """ self.username = urllib2.quote(username) self.password = urllib2.quote(password) + self.AUTH_URL = 'https://{0}/api/login'.format(host) + self.DATA_URL = 'https://{0}/api2/data'.format(host) + self.INDX_URL = 'https://{0}/api2/index?'.format(host) self.token = None def authenticate(self, user, password): @@ -60,7 +60,7 @@ def authenticate(self, user, password): """ auth_params = "email=%s&password=%s" % (user, password) values = base64.encodestring(auth_params) - request = Request(AUTH_URL, values) + request = Request(self.AUTH_URL, values) try: res = urllib2.urlopen(request).read() token = urllib2.quote(res) @@ -105,8 +105,8 @@ def get_note(self, noteid, version=None): params_version = '/' + str(version) params = '/%s%s?auth=%s&email=%s' % (str(noteid), params_version, self.get_token(), self.username) - #logging.debug('REQUEST: ' + DATA_URL+params) - request = Request(DATA_URL+params) + #logging.debug('REQUEST: ' + self.DATA_URL+params) + request = Request(self.DATA_URL+params) try: response = urllib2.urlopen(request) except HTTPError, e: @@ -157,10 +157,10 @@ def update_note(self, note): if 'modifydate' not in note: note["modifydate"] = time.time() - url = '%s/%s?auth=%s&email=%s' % (DATA_URL, note["key"], + url = '%s/%s?auth=%s&email=%s' % (self.DATA_URL, note["key"], self.get_token(), self.username) else: - url = '%s?auth=%s&email=%s' % (DATA_URL, self.get_token(), self.username) + url = '%s?auth=%s&email=%s' % (self.DATA_URL, self.get_token(), self.username) #logging.debug('REQUEST: ' + url + ' - ' + str(note)) request = Request(url, urllib.quote(json.dumps(note))) response = "" @@ -239,8 +239,8 @@ def get_note_list(self, since=None, tags=[]): # perform initial HTTP request try: - #logging.debug('REQUEST: ' + INDX_URL+params) - request = Request(INDX_URL+params) + #logging.debug('REQUEST: ' + self.INDX_URL+params) + request = Request(self.INDX_URL+params) response = json.loads(urllib2.urlopen(request).read()) #logging.debug('RESPONSE OK: ' + str(response)) notes["data"].extend(response["data"]) @@ -256,8 +256,8 @@ def get_note_list(self, since=None, tags=[]): # perform the actual HTTP request try: - #logging.debug('REQUEST: ' + INDX_URL+params) - request = Request(INDX_URL+params) + #logging.debug('REQUEST: ' + self.INDX_URL+params) + request = Request(self.INDX_URL+params) response = json.loads(urllib2.urlopen(request).read()) #logging.debug('RESPONSE OK: ' + str(response)) notes["data"].extend(response["data"]) @@ -316,8 +316,8 @@ def delete_note(self, note_id): params = '/%s?auth=%s&email=%s' % (str(note_id), self.get_token(), self.username) - #logging.debug('REQUEST DELETE: ' + DATA_URL+params) - request = Request(url=DATA_URL+params, method='DELETE') + #logging.debug('REQUEST DELETE: ' + self.DATA_URL+params) + request = Request(url=self.DATA_URL+params, method='DELETE') try: urllib2.urlopen(request) except IOError, e: diff --git a/simplenote_cli/sncli.py b/simplenote_cli/sncli.py @@ -14,8 +14,8 @@ class sncli: - def __init__(self, do_server_sync, verbose=False): - self.config = Config() + def __init__(self, do_server_sync, verbose=False, config_file=None): + self.config = Config(config_file) self.do_server_sync = do_server_sync self.verbose = verbose self.do_gui = False @@ -1150,6 +1150,7 @@ def usage(): -r, --regex - search string is a regular expression -k <key>, --key=<key> - note key -t <title>, --title=<title> - title of note for create (cli mode) + -c <file>, --config=<file> - config file to read from (defaults to ~/.snclirc) COMMANDS: <none> - console gui mode when no command specified @@ -1171,11 +1172,12 @@ def main(argv): regex = False key = None title = None + config = None try: opts, args = getopt.getopt(argv, - 'hvnrk:t:', - [ 'help', 'verbose', 'nosync', 'regex', 'key=', 'title=' ]) + 'hvnrk:t:c:', + [ 'help', 'verbose', 'nosync', 'regex', 'key=', 'title=', 'config=' ]) except: usage() @@ -1192,30 +1194,32 @@ def main(argv): key = arg elif opt in [ '-t', '--title']: title = arg + elif opt in [ '-c', '--config']: + config = arg else: print u'ERROR: Unhandled option' usage() if not args: - sncli(sync).gui(key) + sncli(sync, verbose, config).gui(key) return - def sncli_start(sync, verbose): - sn = sncli(sync, verbose) + def sncli_start(sync=sync, verbose=verbose, config=config): + sn = sncli(sync, verbose, config) if sync: sn.sync_notes() return sn if args[0] == 'sync': - sn = sncli_start(True, verbose) + sn = sncli_start(True) elif args[0] == 'list': - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_list_notes(regex, ' '.join(args[1:])) elif args[0] == 'dump': - sn = sncli_start(sync, verbose) + sn = sncli_start() if key: sn.cli_note_dump(key) else: @@ -1224,10 +1228,10 @@ def sncli_start(sync, verbose): elif args[0] == 'create': if len(args) == 1: - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_create(False, title) elif len(args) == 2 and args[1] == '-': - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_create(True, title) else: usage() @@ -1237,7 +1241,7 @@ def sncli_start(sync, verbose): if not key: usage() - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_edit(key) elif args[0] == 'trash' or args[0] == 'untrash': @@ -1245,7 +1249,7 @@ def sncli_start(sync, verbose): if not key: usage() - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_trash(key, 1 if args[0] == 'trash' else 0) elif args[0] == 'pin' or args[0] == 'unpin': @@ -1253,7 +1257,7 @@ def sncli_start(sync, verbose): if not key: usage() - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_pin(key, 1 if args[0] == 'pin' else 0) elif args[0] == 'markdown' or args[0] == 'unmarkdown': @@ -1261,7 +1265,7 @@ def sncli_start(sync, verbose): if not key: usage() - sn = sncli_start(sync, verbose) + sn = sncli_start() sn.cli_note_markdown(key, 1 if args[0] == 'markdown' else 0) else: