diff options
-rw-r--r-- | README.md | 28 | ||||
-rw-r--r-- | contrib/sncli_to_nn.py | 86 | ||||
-rw-r--r-- | nnotes_cli/__init__.py | 2 | ||||
-rw-r--r-- | nnotes_cli/notes_db.py | 5 | ||||
-rwxr-xr-x | setup.py | 5 |
5 files changed, 110 insertions, 16 deletions
@@ -4,7 +4,7 @@ nncli NextCloud Notes Command Line Interface nncli is a Python application that gives you access to your NextCloud -Notes account via the command line. It's a fork of +Notes account via the command line. It's a "hard" fork of [sncli](https://github.com/insanum/sncli). You can access your notes via a customizable console GUI that implements vi-like keybinds or via a simple command line interface that you can script. @@ -105,12 +105,13 @@ Usage: #### Configuration The current NextCloud Notes API does not support oauth authentication so -your NextCloud Notes account information must live in the configuration -file. Please be sure to protect this file. +your NextCloud Notes account password must be stored someplace +accessible to nncli. Use of the `cfg_nn_password_eval` option is +recommended (see below). nncli pulls in configuration from the `config` file located in your -$XDG_CONFIG_HOME/nncli directory. (By default, -XDG_CONFIG_HOME=$HOME/.config.) At the very least, the following example +`$XDG_CONFIG_HOME/nncli` directory. (By default, +`XDG_CONFIG_HOME=$HOME/.config`.) At the very least, the following example `config` will get you going (using your account information): ``` @@ -133,14 +134,15 @@ See example configuration file below for more notes. ``` [nncli] -cfg_sn_username = lebowski@thedude.com -cfg_sn_password = nihilist +cfg_nn_username = lebowski@thedude.com +cfg_nn_password = nihilist +cfg_nn_host = nextcloud.thedude.com -# as an alternate to cfg_sn_password you could use the following config item +# as an alternate to cfg_nn_password you could use the following config item # any shell command can be used; its stdout is used for the password # trailing newlines are stripped for ease of use -# note: if both password config are given, cfg_sn_password will be used -cfg_sn_password_eval = gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.nncli-pass.gpg +# note: if both password config are given, cfg_nn_password will be used +cfg_nn_password_eval = gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.nncli-pass.gpg # see http://urwid.org/manual/userinput.html for examples of more key # combinations @@ -222,9 +224,11 @@ flags. The following example will do a case-insensitive search for ### Creating from command line ``` -# create a new note and open in editor nncli create +# create a new note and open in editor +nncli create -# create a new note with contents of stdin echo 'hi' | nncli create - +# create a new note with contents of stdin +echo 'hi' | nncli create - ``` ### Importing diff --git a/contrib/sncli_to_nn.py b/contrib/sncli_to_nn.py new file mode 100644 index 0000000..48a5903 --- /dev/null +++ b/contrib/sncli_to_nn.py @@ -0,0 +1,86 @@ +# +# The MIT License (MIT) +# +# Copyright (c) 2018 Daniel Moch +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +""" +sncli_to_nn.py + +Simplenote to NextCloud Notes + +This script imports a folder of json-formatted sncli notes and uploads +them to the specified NextCloud Notes account. + +NOTE: Tags are ignored in the conversion. +""" +import json +import logging +import os +import requests +import sys + +API_URL = 'https://{}:{}@{}/index.php/apps/notes/api/v0.2/notes' + +def convert(sn): + nn = {} + nn['content'] = sn['content'] + nn['modified'] = int(sn['modifydate'].split('.')[0]) + nn['favorite'] = 'true' if 'pinned' in sn['systemtags'] else 'false' + if len(sn['tags']) != 0: + print("WARNING: Ignoring tags in note " + sn['key'] + '.json') + return nn + +def upload(nn, url): + res = requests.post(url, data=nn) + +def sncli_to_nn(sndb_path, nn_host, nn_user, nn_pw): + sndb_path = os.path.expanduser(sndb_path) + url = API_URL.format(nn_user, nn_pw, nn_host) + if not os.path.isdir(sndb_path): + usage("Provided sndb_path does not exist or is not a directory") + + for filename in os.listdir(sndb_path): + if filename.endswith('.json'): + with open(os.path.join(sndb_path, filename), 'r') as notefile: + nn = convert(json.load(notefile)) + + upload(nn, url) + +def usage(message=None): + if message is not None: + print("ERROR: " + message) + + print(""" +Usage: + python3 sncli_to_nn.py sndb_path nn_host nn_user nn_pw + + sndb_path - sncli notes database path + nn_host - NextCloud host + nn_user - NextCloud account username + nn_pw - NextCloud account password +""") + exit(1) + +if __name__ == '__main__': + if len(sys.argv) != 5: + usage("Wrong number of arguments") + + sncli_to_nn(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) diff --git a/nnotes_cli/__init__.py b/nnotes_cli/__init__.py index 8caef83..054095f 100644 --- a/nnotes_cli/__init__.py +++ b/nnotes_cli/__init__.py @@ -1,5 +1,5 @@ __productname__ = 'nncli' -__version__ = '0.1.0' +__version__ = '0.1.1' __copyright__ = "Copyright (c) 2018 Daniel Moch" __author__ = "Daniel Moch" __author_email__ = "daniel@danielmoch.com" diff --git a/nnotes_cli/notes_db.py b/nnotes_cli/notes_db.py index 26bbb2f..c66bedf 100644 --- a/nnotes_cli/notes_db.py +++ b/nnotes_cli/notes_db.py @@ -306,9 +306,8 @@ class NotesDB(): if not isinstance(new_note['content'], str): raise ValueError('"content" must be a string') - for n in (new_note['modified']): - if not 0 <= n <= timestamp: - raise ValueError('date fields must be real') + if not 0 <= new_note['modified'] <= timestamp: + raise ValueError('"modified" field must be real') if not isinstance(new_note['category'], str) or \ new_note['category'] is None: @@ -31,9 +31,14 @@ import nnotes_cli deps = ['urwid', 'requests'] +with open("README.md", "r") as fh: + long_description = fh.read() + setup( name=nnotes_cli.__productname__, description=nnotes_cli.__description__, + long_description=long_description, + long_description_content_type="text/markdown", version=nnotes_cli.__version__, author=nnotes_cli.__author__, author_email=nnotes_cli.__author_email__, |