Moved note handling commands to hooke.plugin.note.
authorW. Trevor King <wking@drexel.edu>
Wed, 12 May 2010 18:46:35 +0000 (14:46 -0400)
committerW. Trevor King <wking@drexel.edu>
Wed, 12 May 2010 18:46:35 +0000 (14:46 -0400)
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
hooke/plugin/__init__.py
hooke/plugin/note.py [new file with mode: 0644]
hooke/plugin/playlist.py
hooke/ui/commandline.py

index 15529864eafde67f5a396f12c372fdb2eb74c6ae..dac1cdc7d539988bc8758abb72222d3bff7436b2 100644 (file)
@@ -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()
index edef66aa98eef405bfdb419670d41617ba0aae15..440c3bfa785f2f5fedbcb8508aa0111f8fb0ef9f 100644 (file)
@@ -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 (file)
index 0000000..4808a3b
--- /dev/null
@@ -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'])
index 343b9643e31512996696b150471cfdb7ca12f551..da2c927428e168525b5542b649ca82ea8b213d2a 100644 (file)
@@ -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')
index 3ab755d61b6180c5175acebdf71b26ab7448491a..8d85a957052a51737ab63c74ffe138873313da1f 100644 (file)
@@ -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()