blob: c5440f7a52f26881f71bf903057a27f0a1157d3d [file]
# SPDX-License-Identifier: GPL-2.0
import json
import os
import _hkml
class Note:
text = None # string
def __init__(self, text):
self.text = text
def to_kvpairs(self):
return {
'text': self.text,
}
@classmethod
def from_kvpairs(cls, kvpairs):
return cls(text=kvpairs['text'])
class Notes:
msgid = None
line_notes = None # line number: Note dict
def __init__(self, msgid, line_notes):
self.msgid = msgid
self.line_notes = line_notes
def to_kvpairs(self):
line_notes_kvpairs = {}
for line_nr, notes in self.line_notes.items():
notes = [note.to_kvpairs() for note in notes]
line_notes_kvpairs[line_nr] = notes
return {
'msgid': self.msgid,
'line_notes': line_notes_kvpairs,
}
@classmethod
def from_kvpairs(cls, kvpairs):
line_notes_kvpairs = kvpairs['line_notes']
line_notes = {}
for line_nr, notes_kvpairs in line_notes_kvpairs.items():
notes = [Note.from_kvpairs(kvp) for kvp in notes_kvpairs]
# json.dump() automatically convert key to string
line_nr = int(line_nr)
line_notes[line_nr] = notes
return cls(msgid=kvpairs['msgid'], line_notes=line_notes)
def mail_notes_file_path():
return os.path.join(_hkml.get_hkml_dir(), 'mail_notes')
def write_mail_notes_file(notes):
kvpairs = {
'mail_notes': [n.to_kvpairs() for n in notes],
}
with open(mail_notes_file_path(), 'w') as f:
json.dump(kvpairs, f, indent=4, sort_keys=True)
def read_mail_notes_file():
file_path = mail_notes_file_path()
if not os.path.isfile(file_path):
return []
with open(file_path, 'r') as f:
kvpairs = json.load(f)
return [Notes.from_kvpairs(kvp) for kvp in kvpairs['mail_notes']]
global_mail_notes = None
def get_mail_notes():
global global_mail_notes
if global_mail_notes is None:
global_mail_notes = read_mail_notes_file()
return global_mail_notes
def get_notes_for(msgid):
full_mail_notes = get_mail_notes()
for mail_notes in full_mail_notes:
if mail_notes.msgid == msgid:
return mail_notes
return None
def add_note(msgid, line_nr, text):
full_mail_notes = get_mail_notes()
notes_list = [n for n in full_mail_notes if n.msgid == msgid]
if len(notes_list) == 0:
notes = Notes(msgid, {})
full_mail_notes.append(notes)
else:
notes = notes_list[0]
if not line_nr in notes.line_notes:
notes.line_notes[line_nr] = []
note = Note(text=text)
notes.line_notes[line_nr].append(note)
write_mail_notes_file(full_mail_notes)
def remove_notes(msgid, line_nr, indices):
deleted = False
full_mail_notes = get_mail_notes()
for notes_idx, notes in enumerate(full_mail_notes):
if notes.msgid != msgid:
continue
if not line_nr in notes.line_notes:
return 'no note for the line number'
line_notes = notes.line_notes[line_nr]
indices.sort(reverse=True)
if len(line_notes) < indices[0] + 1:
return 'too high index'
for idx in indices:
del line_notes[idx]
if len(line_notes) == 0:
del notes.line_notes[line_nr]
if len(notes.line_notes) == 0:
del full_mail_notes[notes_idx]
deleted = True
break
if not deleted:
return 'No note for the msgid?'
write_mail_notes_file(full_mail_notes)
def main(args):
full_mail_notes = get_mail_notes()
if args.action == 'list':
if args.msgid is None:
mail_notes = full_mail_notes
else:
mail_notes = get_notes_for(args.msgid)
if mail_notes is None:
print('no note for the msgid')
exit(1)
mail_notes = [mail_notes]
for mail_note in mail_notes:
for line_nr in sorted(mail_note.line_notes.keys()):
print('%s:%s' % (mail_note.msgid, line_nr))
notes = mail_note.line_notes[line_nr]
for idx, note in enumerate(notes):
print('- %d: %s' % (idx, note.text))
elif args.action == 'add':
add_note(args.msgid, args.line_nr, args.text)
elif args.action == 'remove':
err = remove_notes(args.msgid, args.line_nr, [args.note_idx])
if err is not None:
print(err)
exit(1)
def set_argparser(parser):
parser.description = 'manage notes on mail'
subparsers = parser.add_subparsers(
title='action', dest='action', metavar='<action>')
parser_list = subparsers.add_parser('list', help='list notest')
parser_list.add_argument('--msgid', metavar='<message id>', nargs='+',
help='message id of mails to show notes for')
parser_add = subparsers.add_parser('add', help='add a note')
parser_add.add_argument('msgid', metavar='<message id>',
help='message id of mail to add notes for')
parser_add.add_argument('line_nr', metavar='<line number>', type=int,
help='line number of the mail to add note for')
parser_add.add_argument('text', metavar='<text>',
help='the text note to add')
parser_remove = subparsers.add_parser('remove', help='remove a note')
parser_remove.add_argument('msgid', metavar='<message id>',
help='message id of mail to add notes for')
parser_remove.add_argument('line_nr', metavar='<line number>', type=int,
help='line number of the mail to add note for')
parser_remove.add_argument('note_idx', metavar='<note idx>', type=int,
help='indices of notes to remove')