186 lines
5.1 KiB
Python
186 lines
5.1 KiB
Python
from copy import copy
|
|
from Note import Note
|
|
from Persistent import Persistent
|
|
|
|
|
|
class Notebook( Persistent ):
|
|
"""
|
|
A collection of wiki notes.
|
|
"""
|
|
|
|
class UnknownNoteError( ValueError ):
|
|
"""
|
|
Indicates that an accessed note is not in this notebook.
|
|
"""
|
|
def __init__( self, note_id ):
|
|
ValueError.__init__( self, note_id )
|
|
|
|
def __setstate__( self, state ):
|
|
if "_Notebook__trash" not in state:
|
|
state[ "_Notebook__trash" ] = None
|
|
|
|
self.__dict__.update( state )
|
|
|
|
def __init__( self, id, name, trash = None ):
|
|
"""
|
|
Create a new note with the given id and name.
|
|
|
|
@type id: unicode
|
|
@param id: id of the notebook
|
|
@type name: unicode
|
|
@param name: name of this notebook
|
|
@type trash: Notebook or NoneType
|
|
@param trash: where deleted notes within this Notebook go to die (optional)
|
|
@rtype: Notebook
|
|
@return: newly constructed notebook
|
|
"""
|
|
Persistent.__init__( self, id )
|
|
self.__name = name
|
|
self.__trash = trash
|
|
self.__notes = {} # map of note id to note
|
|
self.__titles = {} # map of note title to note
|
|
self.__startup_notes = [] # list of notes shown on startup
|
|
|
|
def add_note( self, note ):
|
|
"""
|
|
Add a note to this notebook.
|
|
|
|
@type note: Note
|
|
@param note: note to add
|
|
"""
|
|
self.update_revision()
|
|
self.__notes[ note.object_id ] = note
|
|
self.__titles[ note.title ] = note
|
|
|
|
def remove_note( self, note ):
|
|
"""
|
|
Remove a note from this notebook.
|
|
|
|
@type note: Note
|
|
@param note: note to remove
|
|
@rtype: bool
|
|
@return: True if the note was removed, False if the note wasn't in this notebook
|
|
"""
|
|
if self.__notes.pop( note.object_id, None ):
|
|
self.update_revision()
|
|
self.__titles.pop( note.title, None )
|
|
if self.is_startup_note( note ):
|
|
self.__startup_notes.remove( note )
|
|
return True
|
|
|
|
return False
|
|
|
|
def lookup_note( self, note_id ):
|
|
"""
|
|
Return the note in this notebook with the given id.
|
|
|
|
@type note_id: unicode
|
|
@param note_id: id of the note to return
|
|
@rtype: Note or NoneType
|
|
@return: note corresponding to the note id or None
|
|
"""
|
|
return self.__notes.get( note_id )
|
|
|
|
def lookup_note_by_title( self, title ):
|
|
"""
|
|
Return the note in this notebook with the given title.
|
|
|
|
@type title: unicode
|
|
@param title: title of the note to return
|
|
@rtype: Note or NoneType
|
|
@return: note corresponding to the title or None
|
|
"""
|
|
return self.__titles.get( title )
|
|
|
|
def update_note( self, note, contents ):
|
|
"""
|
|
Update the given note with new contents. Bail if the note's contents are unchanged.
|
|
|
|
@type note: Note
|
|
@param note: note to update
|
|
@type contents: unicode
|
|
@param contents: new textual contents for the note
|
|
@raises UnknownNoteError: note to update is not in this notebook
|
|
"""
|
|
old_note = self.__notes.get( note.object_id )
|
|
if old_note is None:
|
|
raise Notebook.UnknownNoteError( note.object_id )
|
|
|
|
self.update_revision()
|
|
self.__titles.pop( note.title, None )
|
|
|
|
note.contents = contents
|
|
|
|
self.__titles[ note.title ] = note
|
|
|
|
def add_startup_note( self, note ):
|
|
"""
|
|
Add the given note to be shown on startup. It must already be a note in this notebook.
|
|
|
|
@type note: Note
|
|
@param note: note to be added for startup
|
|
@rtype: bool
|
|
@return: True if the note was added for startup
|
|
@raises UnknownNoteError: given note is not in this notebook
|
|
"""
|
|
if self.__notes.get( note.object_id ) is None:
|
|
raise Notebook.UnknownNoteError( note.object_id )
|
|
|
|
if not self.is_startup_note( note ):
|
|
self.update_revision()
|
|
self.__startup_notes.append( note )
|
|
return True
|
|
|
|
return False
|
|
|
|
def remove_startup_note( self, note ):
|
|
"""
|
|
Remove the given note from being shown on startup.
|
|
|
|
@type note: Note
|
|
@param note: note to be removed from startup
|
|
@rtype: bool
|
|
@return: True if the note was removed from startup
|
|
"""
|
|
if self.is_startup_note( note ):
|
|
self.update_revision()
|
|
self.__startup_notes.remove( note )
|
|
return True
|
|
|
|
return False
|
|
|
|
def is_startup_note( self, note ):
|
|
"""
|
|
Return whether the given note is a startup note.
|
|
|
|
@type note: Note
|
|
@param note: note to test for startup status
|
|
@rtype bool
|
|
@return: True if the note is a startup note
|
|
"""
|
|
return note.object_id in [ n.object_id for n in self.__startup_notes if n ]
|
|
|
|
def to_dict( self ):
|
|
d = Persistent.to_dict( self )
|
|
|
|
# as an optimization, don't include the revisions list because it's not
|
|
# currently used anywhere for Notebook objects
|
|
del d[ "revisions_list" ]
|
|
|
|
d.update( dict(
|
|
name = self.__name,
|
|
trash = self.__trash,
|
|
read_write = True,
|
|
) )
|
|
|
|
return d
|
|
|
|
def __set_name( self, name ):
|
|
self.__name = name
|
|
self.update_revision()
|
|
|
|
name = property( lambda self: self.__name, __set_name )
|
|
trash = property( lambda self: self.__trash )
|
|
startup_notes = property( lambda self: [ note for note in copy( self.__startup_notes ) if note is not None ] )
|
|
notes = property( lambda self: [ note for note in self.__notes.values() if note is not None ] )
|