You can now print an individual note.
This commit is contained in:
parent
c262ad7b00
commit
7def0fe58c
2
NEWS
2
NEWS
|
@ -1,6 +1,8 @@
|
||||||
1.6.8: ?
|
1.6.8: ?
|
||||||
* You can now print your entire notebook. Just click the "print" link on the
|
* You can now print your entire notebook. Just click the "print" link on the
|
||||||
left side of the page.
|
left side of the page.
|
||||||
|
* You can now print an individual note. Just click the "options" tab on a
|
||||||
|
note and then "print this note".
|
||||||
* Changed the order of exported HTML and CSV notebooks so that after all the
|
* Changed the order of exported HTML and CSV notebooks so that after all the
|
||||||
"startup" notes are included, the remaining notes are included in
|
"startup" notes are included, the remaining notes are included in
|
||||||
alphabetical order (instead of reverse chronological order).
|
alphabetical order (instead of reverse chronological order).
|
||||||
|
|
|
@ -1196,16 +1196,19 @@ class Notebooks( object ):
|
||||||
@validate(
|
@validate(
|
||||||
notebook_id = Valid_id(),
|
notebook_id = Valid_id(),
|
||||||
format = Valid_string( min = 1, max = 100 ),
|
format = Valid_string( min = 1, max = 100 ),
|
||||||
|
note_id = Valid_id( none_okay = True ),
|
||||||
user_id = Valid_id( none_okay = True ),
|
user_id = Valid_id( none_okay = True ),
|
||||||
)
|
)
|
||||||
def export( self, notebook_id, format, user_id ):
|
def export( self, notebook_id, format, note_id = None, user_id = None ):
|
||||||
"""
|
"""
|
||||||
Download the entire contents of the given notebook as a stand-alone file.
|
Download the entire contents of the given notebook as a stand-alone file.
|
||||||
|
|
||||||
@type notebook_id: unicode
|
@type notebook_id: unicode
|
||||||
@param notebook_id: id of notebook to download
|
@param notebook_id: id of notebook to export
|
||||||
@type format: unicode
|
@type format: unicode
|
||||||
@param format: string indicating the export plugin to use, currently one of: "html", "csv"
|
@param format: string indicating the export plugin to use, currently one of: "html", "csv"
|
||||||
|
@type notebook_id: unicode
|
||||||
|
@param note_id: id of single note within the notebook to export (optional)
|
||||||
@type user_id: unicode
|
@type user_id: unicode
|
||||||
@param user_id: id of current logged-in user (if any), determined by @grab_user_id
|
@param user_id: id of current logged-in user (if any), determined by @grab_user_id
|
||||||
@rtype: unicode or generator (for streaming files)
|
@rtype: unicode or generator (for streaming files)
|
||||||
|
@ -1221,9 +1224,16 @@ class Notebooks( object ):
|
||||||
if not notebook:
|
if not notebook:
|
||||||
raise Access_error()
|
raise Access_error()
|
||||||
|
|
||||||
startup_notes = self.__database.select_many( Note, notebook.sql_load_startup_notes() )
|
if note_id:
|
||||||
other_notes = self.__database.select_many( Note, notebook.sql_load_non_startup_notes() )
|
note = self.__database.load( Note, note_id )
|
||||||
notes = startup_notes + other_notes
|
if not note:
|
||||||
|
raise Access_error()
|
||||||
|
notes = [ note ]
|
||||||
|
notebook = None
|
||||||
|
else:
|
||||||
|
startup_notes = self.__database.select_many( Note, notebook.sql_load_startup_notes() )
|
||||||
|
other_notes = self.__database.select_many( Note, notebook.sql_load_non_startup_notes() )
|
||||||
|
notes = startup_notes + other_notes
|
||||||
|
|
||||||
from plugins.Invoke import invoke
|
from plugins.Invoke import invoke
|
||||||
|
|
||||||
|
@ -1233,7 +1243,7 @@ class Notebooks( object ):
|
||||||
plugin_name = format,
|
plugin_name = format,
|
||||||
database = self.__database,
|
database = self.__database,
|
||||||
notebook = notebook,
|
notebook = notebook,
|
||||||
notes = startup_notes + other_notes,
|
notes = notes,
|
||||||
response_headers = cherrypy.response.headerMap,
|
response_headers = cherrypy.response.headerMap,
|
||||||
)
|
)
|
||||||
except ( ImportError, AttributeError ):
|
except ( ImportError, AttributeError ):
|
||||||
|
|
|
@ -4801,6 +4801,45 @@ class Test_notebooks( Test_controller ):
|
||||||
|
|
||||||
assert u"access" in result[ "body" ][ 0 ]
|
assert u"access" in result[ "body" ][ 0 ]
|
||||||
|
|
||||||
|
def test_export_print_with_note_id( self ):
|
||||||
|
self.login()
|
||||||
|
|
||||||
|
note3 = Note.create( "55", u"<h3>blah</h3>foo", notebook_id = self.notebook.object_id )
|
||||||
|
self.database.save( note3 )
|
||||||
|
|
||||||
|
result = self.http_get(
|
||||||
|
"/notebooks/export?notebook_id=%s&format=print¬e_id=%s" % ( self.notebook.object_id, note3.object_id ),
|
||||||
|
session_id = self.session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.get( "notebook" ) == None
|
||||||
|
assert result.get( "view" )
|
||||||
|
|
||||||
|
notes = result.get( "notes" )
|
||||||
|
assert len( notes ) == 1
|
||||||
|
note = notes[ 0 ]
|
||||||
|
|
||||||
|
assert note.object_id == note3.object_id
|
||||||
|
assert note.revision == note3.revision
|
||||||
|
assert note.title == note3.title
|
||||||
|
assert note.contents == note3.contents
|
||||||
|
assert note.notebook_id == note3.notebook_id
|
||||||
|
assert note.startup == note3.startup
|
||||||
|
assert note.deleted_from_id == note3.deleted_from_id
|
||||||
|
assert note.rank == note3.rank
|
||||||
|
assert note.user_id == note3.user_id
|
||||||
|
assert note.creation == note3.creation
|
||||||
|
|
||||||
|
def test_export_print_with_unknown_note_id( self ):
|
||||||
|
self.login()
|
||||||
|
|
||||||
|
result = self.http_get(
|
||||||
|
"/notebooks/export?notebook_id=%s&format=print¬e_id=%s" % ( self.notebook.object_id, self.unknown_note_id ),
|
||||||
|
session_id = self.session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert u"access" in result[ "body" ][ 0 ]
|
||||||
|
|
||||||
def test_create( self ):
|
def test_create( self ):
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Html_file( Html ):
|
||||||
contents = self.IMAGE_PATTERN.sub( '', contents )
|
contents = self.IMAGE_PATTERN.sub( '', contents )
|
||||||
relinked_notes[ note.object_id ] = contents
|
relinked_notes[ note.object_id ] = contents
|
||||||
|
|
||||||
response_headers[ u"Content-Disposition" ] = u"attachment; filename=%s.html" % notebook.friendly_id
|
response_headers[ u"Content-Disposition" ] = u"attachment; filename=%s.html" % notebook and notebook.friendly_id
|
||||||
|
|
||||||
Html.__init__(
|
Html.__init__(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -19,11 +19,11 @@ class Print_notes( Html ):
|
||||||
Style( file( u"static/css/download.css" ).read(), type = u"text/css" ),
|
Style( file( u"static/css/download.css" ).read(), type = u"text/css" ),
|
||||||
Style( file( u"static/css/print.css" ).read(), type = u"text/css" ),
|
Style( file( u"static/css/print.css" ).read(), type = u"text/css" ),
|
||||||
Meta( content = u"text/html; charset=UTF-8", http_equiv = u"content-type" ),
|
Meta( content = u"text/html; charset=UTF-8", http_equiv = u"content-type" ),
|
||||||
Title( notebook.name ),
|
Title( notebook and notebook.name or notes[ 0 ].title ),
|
||||||
),
|
),
|
||||||
Body(
|
Body(
|
||||||
Div(
|
Div(
|
||||||
H1( notebook.name ),
|
notebook and H1( notebook.name ) or None,
|
||||||
[ Span(
|
[ Span(
|
||||||
A( name = u"note_%s" % note.object_id ),
|
A( name = u"note_%s" % note.object_id ),
|
||||||
Div(
|
Div(
|
||||||
|
|
|
@ -73,3 +73,37 @@ class Test_export_html( object ):
|
||||||
assert note.rank == expected_note.rank
|
assert note.rank == expected_note.rank
|
||||||
assert note.user_id == expected_note.user_id
|
assert note.user_id == expected_note.user_id
|
||||||
assert note.creation == expected_note.creation
|
assert note.creation == expected_note.creation
|
||||||
|
|
||||||
|
def test_export_print_without_notebook( self ):
|
||||||
|
note3 = Note.create( "55", u"<h3>blah</h3>foo", notebook_id = self.notebook.object_id )
|
||||||
|
self.database.save( note3 )
|
||||||
|
response_headers = {}
|
||||||
|
expected_notes = ( self.note1, self.note2, note3 )
|
||||||
|
|
||||||
|
result = invoke(
|
||||||
|
"export",
|
||||||
|
"print",
|
||||||
|
self.database,
|
||||||
|
None,
|
||||||
|
expected_notes,
|
||||||
|
response_headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
# response headers should be unchanged
|
||||||
|
assert response_headers == {}
|
||||||
|
|
||||||
|
notes = result.get( "notes" )
|
||||||
|
assert len( notes ) == len( expected_notes )
|
||||||
|
|
||||||
|
# assert that the notes are in the expected order
|
||||||
|
for ( note, expected_note ) in zip( notes, expected_notes ):
|
||||||
|
assert note.object_id == expected_note.object_id
|
||||||
|
assert note.revision == expected_note.revision
|
||||||
|
assert note.title == expected_note.title
|
||||||
|
assert note.contents == expected_note.contents
|
||||||
|
assert note.notebook_id == expected_note.notebook_id
|
||||||
|
assert note.startup == expected_note.startup
|
||||||
|
assert note.deleted_from_id == expected_note.deleted_from_id
|
||||||
|
assert note.rank == expected_note.rank
|
||||||
|
assert note.user_id == expected_note.user_id
|
||||||
|
assert note.creation == expected_note.creation
|
||||||
|
|
|
@ -3217,9 +3217,19 @@ function Options_pulldown( wiki, notebook_id, invoker, editor ) {
|
||||||
this.startup_label = createDOM( "label", { "for": "startup_checkbox", "class": "pulldown_label", "title": "Display this note whenever the notebook is loaded." },
|
this.startup_label = createDOM( "label", { "for": "startup_checkbox", "class": "pulldown_label", "title": "Display this note whenever the notebook is loaded." },
|
||||||
"show on startup"
|
"show on startup"
|
||||||
);
|
);
|
||||||
|
this.print_checkbox = createDOM( "input", { "type": "checkbox", "class": "pulldown_checkbox invisible" } );
|
||||||
|
this.print_link = createDOM( "a",
|
||||||
|
{
|
||||||
|
"href": "/notebooks/export?notebook_id=" + notebook_id + "¬e_id=" + editor.id + "&format=print",
|
||||||
|
"target": "_new",
|
||||||
|
"class": "pulldown_link",
|
||||||
|
"title": "Print this note by itself."
|
||||||
|
},
|
||||||
|
"print this note"
|
||||||
|
);
|
||||||
|
|
||||||
appendChildNodes( this.div, this.startup_checkbox );
|
appendChildNodes( this.div, createDOM( "div", {}, this.startup_checkbox, this.startup_label ) );
|
||||||
appendChildNodes( this.div, this.startup_label );
|
appendChildNodes( this.div, createDOM( "div", {}, this.print_checkbox, this.print_link ) );
|
||||||
this.startup_checkbox.checked = editor.startup;
|
this.startup_checkbox.checked = editor.startup;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
Reference in New Issue