From 6b3e141f9acc6ac7dffb9075891ba5fb4adad59e Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 12 May 2010 14:46:35 -0400 Subject: [PATCH] Moved note handling commands to hooke.plugin.note. Also: * Fixed graph dependency creation in hooke.plugin.construct_graph. The previous implemetation had Plugin instances as parents, not Node instances. * Moved a few builtin modules from hooke.plugin.PLUGIN_MODULES to .BUILTIN_MODULES. * Fixup unsaved playlist detection in hooke.ui.commandline.LocalExitCommand._run --- hooke/hooke_cli.py | 67 ------------------------ hooke/plugin/__init__.py | 14 +++-- hooke/plugin/note.py | 108 +++++++++++++++++++++++++++++++++++++++ hooke/plugin/playlist.py | 2 + hooke/ui/commandline.py | 9 ++-- 5 files changed, 124 insertions(+), 76 deletions(-) create mode 100644 hooke/plugin/note.py diff --git a/hooke/hooke_cli.py b/hooke/hooke_cli.py index 1552986..dac1cdc 100644 --- a/hooke/hooke_cli.py +++ b/hooke/hooke_cli.py @@ -491,70 +491,3 @@ Syntax: txt [filename] {plot to export} txtfile.close() - #LOGGING, REPORTING, NOTETAKING - - - def do_note_old(self,args): - ''' - NOTE_OLD - **deprecated**: Use note instead. Will be removed in 0.9 - - Writes or displays a note about the current curve. - If [anything] is empty, it displays the note, otherwise it adds a note. - The note is then saved in the playlist if you issue a savelist command - --------------- - Syntax: note_old [anything] - - ''' - if args=='': - print self.current_list[self.pointer].notes - else: - #bypass UnicodeDecodeError troubles - try: - args=args.decode('ascii') - except: - args=args.decode('ascii','ignore') - if len(args)==0: - args='?' - - self.current_list[self.pointer].notes=args - self.notes_saved=0 - - - def do_note(self,args): - ''' - NOTE - - Writes or displays a note about the current curve. - If [anything] is empty, it displays the note, otherwise it adds a note. - The note is then saved in the playlist if you issue a savelist command. - --------------- - Syntax: note_old [anything] - - ''' - if args=='': - print self.current_list[self.pointer].notes - else: - if self.notes_filename == None: - if not os.path.exists(os.path.realpath('output')): - os.mkdir('output') - self.notes_filename=raw_input('Notebook filename? ') - self.notes_filename=os.path.join(os.path.realpath('output'),self.notes_filename) - title_line='Notes taken at '+time.asctime()+'\n' - f=open(self.notes_filename,'a') - f.write(title_line) - f.close() - - #bypass UnicodeDecodeError troubles - try: - args=args.decode('ascii') - except: - args=args.decode('ascii','ignore') - if len(args)==0: - args='?' - self.current_list[self.pointer].notes=args - - f=open(self.notes_filename,'a+') - note_string=(self.current.path+' | '+self.current.notes+'\n') - f.write(note_string) - f.close() diff --git a/hooke/plugin/__init__.py b/hooke/plugin/__init__.py index edef66a..440c3bf 100644 --- a/hooke/plugin/__init__.py +++ b/hooke/plugin/__init__.py @@ -14,7 +14,6 @@ PLUGIN_MODULES = [ # ('autopeak', True), # ('curvetools', True), ('cut', True), - ('debug', True), # ('fit', True), # ('flatfilts-rolf', True), # ('flatfilts', True), @@ -32,7 +31,6 @@ PLUGIN_MODULES = [ # ('review', True), # ('showconvoluted', True), # ('superimpose', True), - ('system', True), # ('tutorial', True), ] """List of plugin modules and whether they should be included by @@ -40,7 +38,10 @@ default. TODO: autodiscovery """ BUILTIN_MODULES = [ + 'debug', + 'note', 'playlist', + 'system', ] """List of builtin modules. TODO: autodiscovery """ @@ -122,9 +123,12 @@ def construct_graph(this_modname, submodnames, class_selector, 'Instance name %s does not match module name %s' % (instance.name, submodname)) instances[instance.name] = instance - graph = Graph([Node([instances[name] for name in i.dependencies()], - data=i) - for i in instances.values()]) + nodes = {} + for i in instances.values(): # make nodes for each instance + nodes[i.name] = Node(data=i) + for n in nodes.values(): # fill in dependencies for each node + n.extend([nodes[name] for name in n.data.dependencies()]) + graph = Graph(nodes.values()) graph.topological_sort() return graph diff --git a/hooke/plugin/note.py b/hooke/plugin/note.py new file mode 100644 index 0000000..4808a3b --- /dev/null +++ b/hooke/plugin/note.py @@ -0,0 +1,108 @@ +"""The `note` module provides :class:`NotePlugin` the associated +:class:`hooke.command.Command`\s for annotating several Hooke classes +(:mod:`hooke.playlist.Playlist`, :mod:`hooke.curve.Curve`, ...). +""" + +from ..command import Command, Argument, Failure +from ..playlist import FilePlaylist +from ..plugin import Builtin +from ..plugin.playlist import current_playlist_callback + + +class NotePlugin (Builtin): + def __init__(self): + super(NotePlugin, self).__init__(name='note') + + def commands(self): + return [AddNoteCommand(), ClearNoteCommand(), GetNoteCommand()] + + def dependencies(self): + return [ + 'playlist', # for current_playlist_callback + ] + + +class AddNoteCommand (Command): + """Add a note to one of several Hooke objects. + """ + def __init__(self): + super(AddNoteCommand, self).__init__( + name='add note', + arguments=[ + Argument( + name='target', type='object', + callback=current_playlist_callback, + help=""" +Target object for the note. Defaults to the current playlist. +""".strip()), + Argument( + name='note', type='string', optional=False, + help=""" +The note text. +""".strip()), + ], + help=self.__doc__) + + def _run(self, hooke, inqueue, outqueue, params): + params['target'].info['note'].append(params['note']) + +class ClearNoteCommand (Command): + """Remove a note or notes from one of several Hooke objects. + """ + def __init__(self): + super(ClearNoteCommand, self).__init__( + name='clear note', + arguments=[ + Argument( + name='target', type='object', + callback=current_playlist_callback, + help=""" +Target object for the note. Defaults to the current playlist. +""".strip()), + Argument(name='count', type='int', default=-1, + help=""" +Number of notes to remove. Defaults to all notes. +""".strip()), + Argument(name='force', type='bool', default=False, + help=""" +Run without prompting the user. Use if you save often or don't make +typing mistakes ;). +""".strip()), + ], + help=self.__doc__) + + def _run(self, hooke, inqueue, outqueue, params): + num_notes = len(params['target'].info['note']) + if params['count'] == -1: + num_notes_removed = num_notes + else: + num_notes_removed = min(num_notes, params['count']) + if params['force'] == False and num_notes_removed > 0: + msg = 'Remove %d notes?' % num_notes_removed + default = False + outqueue.put(BooleanRequest(msg, default)) + result = inqueue.get() + assert result.type == 'boolean' + if result.value == False: + return + params['target'].info['note'] = \ + params['target'].info['note'][:-num_notes_removed] + +class GetNoteCommand (Command): + """Retrieve notes from one of several Hooke objects. + """ + def __init__(self): + super(GetNoteCommand, self).__init__( + name='get note', + arguments=[ + Argument( + name='target', type='object', + callback=current_playlist_callback, + help=""" +Target object for the note. Defaults to the current playlist. +""".strip()), + ], + help=self.__doc__) + + def _run(self, hooke, inqueue, outqueue, params): + outqueue.put(params['target'].info['note']) diff --git a/hooke/plugin/playlist.py b/hooke/plugin/playlist.py index 343b964..da2c927 100644 --- a/hooke/plugin/playlist.py +++ b/hooke/plugin/playlist.py @@ -24,6 +24,8 @@ class PlaylistPlugin (Builtin): # Define common or complicated arguments def current_playlist_callback(hooke, command, argument, value): + if value != None: + return value playlist = hooke.playlists.current() if playlist == None: raise Failure('No playlists loaded') diff --git a/hooke/ui/commandline.py b/hooke/ui/commandline.py index 3ab755d..8d85a95 100644 --- a/hooke/ui/commandline.py +++ b/hooke/ui/commandline.py @@ -292,12 +292,13 @@ typing mistakes ;). """ _exit = True if params['force'] == False: - # TODO: get results of hooke.playlists.current().is_saved() - is_saved = True + not_saved = [p.name for p in hooke.playlists + if p.is_saved() == False] msg = 'Exit?' default = True - if is_saved == False: - msg = 'You did not save your playlist. ' + msg + if len(not_saved) > 0: + msg = 'Unsaved playlists (%s). %s' \ + % (', '.join(not_saved), msg) default = False outqueue.put(BooleanRequest(msg, default)) result = inqueue.get() -- 2.26.2