Skip to content

Commit

Permalink
Support notes with checkboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
Drarig29 committed Jun 5, 2021
1 parent 4d7ced4 commit 06f4764
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
__pycache__
/dist
/*.egg-info
build
32 changes: 32 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Debug",
"type": "python",
"request": "launch",
"program": "./gkeep",
"args": [
"notes",

// "get",
// "1622667139340.93561477"

"edit",
"--filter-id",
"1622667139340.93561477",
"--text"

// "edit",
// "--filter-title",
// "TODOloulou",
// "--text",
// "coucou"
],
"console": "integratedTerminal"
}
]
}
33 changes: 33 additions & 0 deletions chardetect
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'chardet','console_scripts','chardetect'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'chardet'

try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point


def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()


globals().setdefault('load_entry_point', importlib_load_entry_point)


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('chardet', 'console_scripts', 'chardetect')())
33 changes: 33 additions & 0 deletions futurize
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'future','console_scripts','futurize'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'future'

try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point


def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()


globals().setdefault('load_entry_point', importlib_load_entry_point)


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('future', 'console_scripts', 'futurize')())
33 changes: 33 additions & 0 deletions gkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'gkeep','console_scripts','gkeep'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'gkeep'

try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point


def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()


globals().setdefault('load_entry_point', importlib_load_entry_point)


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('gkeep', 'console_scripts', 'gkeep')())
2 changes: 2 additions & 0 deletions gkeep.egg-link
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/home/corentin/playground/gkeep
.
89 changes: 85 additions & 4 deletions google_keep_tasks/notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import click
import gkeepapi
import sys
import re

from gkeepapi.node import List

from google_keep_tasks.cli import GkeepGroup
from google_keep_tasks.exceptions import InvalidColor
Expand Down Expand Up @@ -73,6 +76,21 @@ def query_params(keep, **kwargs):
set(x.labels.all()) == set(labels) if labels is not None else None]))
return kwargs

def format_note_item(item):
return u'%s%s %s' % (
' ' if item.indented else '',
u'- [x]' if item.checked else u'- [ ]',
item.text
)

def format_note(note):
if not isinstance(note, List):
return note.text
text = ""
for item in note.items:
text += "%s | %s\n" % (item.id.ljust(30), format_note_item(item))
return text


def print_note(note):
params = COLORS.get(note.color, {})
Expand All @@ -82,15 +100,74 @@ def print_note(note):
click.echo(click.style('"' * len(note_id), **params))
if note.title:
click.echo(click.style(note.title, bold=True))
click.echo(note.text)
click.echo('-' * len(note_id))
click.echo(format_note(note))
click.echo('-' * len(note_id))
if note.labels:
click.echo()
click.echo(' '.join(click.style('[{}]'.format(label.name), underline=True, bold=True)
for label in note.labels.all()))
click.echo(click.style('"' * len(note_id), **params))
click.echo('\n')


def edit_note_checkboxes(note):
text = click.edit(format_note(note)).strip()
lines = text.split("\n")
regex = re.compile(r"([\w.]*) *\| ( *)- \[(x| )\] (.*)")

last_old_note = 'top'
current_items = []
for line in lines:
id, indent, check_mark, content = regex.match(line).groups()
found = list(filter(lambda item: item.id == id, note.items))
old_note = found[0] if len(found) > 0 else None
indented = len(indent) > 1
checked = check_mark == 'x'
current_items.append({
'id': id,
'previous': last_old_note,
'old': old_note,
'indented': indented,
'checked': checked,
'content': content
})
last_old_note = old_note

# Deletion
for item in note.items:
if item.id not in [parts['id'] for parts in current_items]:
item.delete()

last_added = None
for parts in current_items:
previous = parts['previous'] if parts['previous'] != None else last_added

# Addition
if parts['old'] == None:
sort = int(previous.sort) - 1 if previous != None and previous != 'top' else gkeepapi.node.NewListItemPlacementValue.Top
added = note.add(parts['content'], parts['checked'], sort)
if parts['indented']:
previous.indent(added)
last_added = added

# Modification
else:
if parts['old'].indented and not parts['indented']:
if previous != None:
previous.dedent(parts['old'])
if not parts['old'].indented and parts['indented']:
if previous != None:
previous.indent(parts['old'])

if parts['old'].checked and not parts['checked']:
parts['old'].checked = False
if not parts['old'].checked and parts['checked']:
parts['old'].checked = True

if parts['old'].text != parts['content']:
parts['old'].text = parts['content']


def get_note_instance(keep, id=None, **kwargs):
if id:
note = keep.get(id)
Expand Down Expand Up @@ -234,7 +311,11 @@ def edit_note(ctx, title, text, color, labels, archived, pinned, filter_id, filt
click.echo('The note was not found', err=True)
sys.exit(2)
if text == placeholder:
text = click.edit(note.text).strip()
if isinstance(note, List):
edit_note_checkboxes(note)
text = None
else:
text = click.edit(note.text).strip()
updated = {}
boolean_nullables = ['archived', 'pinned'] # 3 state params
for param in ['title', 'text', 'color', 'labels'] + boolean_nullables:
Expand Down Expand Up @@ -275,4 +356,4 @@ def delete_note(ctx, **kwargs):
click.echo('Note with title "{}" deleted.'.format(note.title))
else:
click.echo('The note was not found', err=True)
sys.exit(2)
sys.exit(2)
33 changes: 33 additions & 0 deletions pasteurize
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'future','console_scripts','pasteurize'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'future'

try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point


def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()


globals().setdefault('load_entry_point', importlib_load_entry_point)


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('future', 'console_scripts', 'pasteurize')())

0 comments on commit 06f4764

Please sign in to comment.