diff --git a/controller/Root.py b/controller/Root.py index 49980f1..d132359 100644 --- a/controller/Root.py +++ b/controller/Root.py @@ -10,6 +10,7 @@ from model.Note import Note from model.Notebook import Notebook from model.User import User from view.Main_page import Main_page +from view.Notebook_rss import Notebook_rss from view.Json import Json from view.Error_page import Error_page from view.Not_found_page import Not_found_page @@ -111,14 +112,15 @@ class Root( object ): return result - @expose( view = Main_page ) + @expose( view = Main_page, rss = Notebook_rss ) @grab_user_id @validate( start = Valid_int( min = 0 ), count = Valid_int( min = 1, max = 50 ), + note_id = Valid_id( none_okay = True ), user_id = Valid_id( none_okay = True ), ) - def blog( self, start = 0, count = 3, user_id = None ): + def blog( self, start = 0, count = 5, note_id = None, user_id = None ): """ Provide the information necessary to display the blog notebook with notes in reverse chronological order. @@ -136,6 +138,12 @@ class Root( object ): result.update( self.__notebooks.load_recent_notes( blog_notebooks[ 0 ].object_id, start, count, user_id ) ) + # if a single note was requested, just return that one note + if note_id: + result[ "notes" ] = [ note for note in result[ "notes" ] if note.object_id == note_id ] + + result[ "http_url" ] = self.__settings[ u"global" ].get( u"luminotes.http_url", u"" ) + return result @expose( view = Main_page ) diff --git a/controller/test/Test_root.py b/controller/test/Test_root.py index 57f1e77..735e11a 100644 --- a/controller/test/Test_root.py +++ b/controller/test/Test_root.py @@ -124,6 +124,23 @@ class Test_root( Test_controller ): ) assert result + assert u"error" not in result + + def test_blog_with_note_id( self ): + result = self.http_get( + "/blog?note_id=%s" % self.blog_note.object_id, + ) + + assert result + assert u"error" not in result + + def test_blog_rss( self ): + result = self.http_get( + "/blog?rss", + ) + + assert result + assert u"error" not in result def test_guide( self ): result = self.http_get( @@ -131,6 +148,7 @@ class Test_root( Test_controller ): ) assert result + assert u"error" not in result def test_next_id( self ): result = self.http_get( "/next_id" ) diff --git a/view/Link_area.py b/view/Link_area.py index d1926f8..0723895 100644 --- a/view/Link_area.py +++ b/view/Link_area.py @@ -3,7 +3,7 @@ from Rounded_div import Rounded_div class Link_area( Div ): - def __init__( self, notebooks, notebook, total_notes_count, parent_id ): + def __init__( self, notebooks, notebook, total_notes_count, parent_id, notebook_path ): linked_notebooks = [ nb for nb in notebooks if nb.read_write and nb.name not in ( u"trash" ) ] Div.__init__( @@ -34,6 +34,16 @@ class Link_area( Div ): class_ = u"link_area_item", ) or None, + ( notebook.name == u"Luminotes blog" ) and Div ( + A( + u"subscribe to rss", + href = u"%s?rss" % notebook_path, + id = u"rss link", + title = u"Subscribe to the RSS feed for the Luminotes blog.", + ), + class_ = u"link_area_item", + ) or None, + notebook.read_write and Span( notebook.trash_id and Div( A( diff --git a/view/Main_page.py b/view/Main_page.py index 14a72b7..3bd1e52 100644 --- a/view/Main_page.py +++ b/view/Main_page.py @@ -25,6 +25,7 @@ class Main_page( Page ): note_read_write = True, start = None, count = None, + http_url = None, ): startup_note_ids = [ startup_note.object_id for startup_note in startup_notes ] @@ -93,7 +94,7 @@ class Main_page( Page ): Toolbar( hide_toolbar = not notebook.read_write ), id = u"toolbar_area", ), - Link_area( notebooks, notebook, total_notes_count, parent_id ), + Link_area( notebooks, notebook, total_notes_count, parent_id, notebook_path ), Div( Div( Div( @@ -146,7 +147,7 @@ class Main_page( Page ): type = u"text/javascript", ), # make page navigation for those notebooks that require it (such as the blog) - ( start is not None and count is not None ) and Div( + ( start is not None and count is not None and len( notes ) > 1 ) and Div( ( start > 0 ) and Div( A( u"previous page", href = "%s?start=%d&count=%d" % ( notebook_path, max( start - count, 0 ), count ), diff --git a/view/Notebook_rss.py b/view/Notebook_rss.py new file mode 100644 index 0000000..60c5950 --- /dev/null +++ b/view/Notebook_rss.py @@ -0,0 +1,47 @@ +import cgi +from Rss_channel import Rss_channel +from Rss_item import Rss_item + + +class Notebook_rss( Rss_channel ): + def __init__( + self, + user, + rate_plan, + notebooks, + notebook, + parent_id = None, + login_url = None, + logout_url = None, + startup_notes = None, + total_notes_count = None, + notes = None, + note_read_write = True, + start = None, + count = None, + http_url = u"", + ): + if notebook.name == u"Luminotes": + notebook_path = u"/" + elif notebook.name == u"Luminotes user guide": + notebook_path = u"/guide" + elif notebook.name == u"Luminotes blog": + notebook_path = u"/blog" + else: + notebook_path = u"/notebooks/%s" % notebook.object_id + + notebook_path = http_url + notebook_path + + Rss_channel.__init__( + self, + notebook.name, + notebook_path, + notebook.name, + [ Rss_item( + title = cgi.escape( note.title ), + link = u"%s?note_id=%s" % ( notebook_path, note.object_id ), + description = cgi.escape( note.contents ), + date = note.creation.strftime( "%Y-%m-%dT%H:%M:%SZ" ), + guid = u"%s?note_id=%s" % ( notebook_path, note.object_id ), + ) for note in notes ], + ) diff --git a/view/Rss_channel.py b/view/Rss_channel.py new file mode 100644 index 0000000..a4102b8 --- /dev/null +++ b/view/Rss_channel.py @@ -0,0 +1,19 @@ +from Rss_tags import Rss, Channel, Title, Link, Description, Language + + +class Rss_channel( Rss ): + MAX_ITEMS = 20 + + def __init__( self, title, link, description, rss_items, language = None ): + Rss.__init__( + self, + Channel( + Title( u"%s" % title ), + Link( link ), + Description( description ), + Language( language or u"en-us" ), + rss_items[ : self.MAX_ITEMS ], + ), + version = u"2.0", + xmlns_dc = u"http://purl.org/dc/elements/1.1/", + ) diff --git a/view/Rss_item.py b/view/Rss_item.py new file mode 100644 index 0000000..f2c7acd --- /dev/null +++ b/view/Rss_item.py @@ -0,0 +1,13 @@ +from Rss_tags import Item, Title, Link, Description, Dc_date, Dc_creator, Guid + + +class Rss_item( Item ): + def __init__( self, title, link, description, date, guid ): + Item.__init__( + self, + Title( title ), + Link( link ), + Description( description ), + Dc_date( date ), + Guid( guid ), + ) diff --git a/view/Rss_tags.py b/view/Rss_tags.py new file mode 100644 index 0000000..ec8be11 --- /dev/null +++ b/view/Rss_tags.py @@ -0,0 +1,13 @@ +from Node import Node + + +class Rss( Node ): tag = u"rss" +class Channel( Node ): tag = u"channel" +class Title( Node ): tag = u"title" +class Link( Node ): tag = u"link" +class Description( Node ): tag = u"description" +class Language( Node ): tag = u"language" +class Item( Node ): tag = u"item" +class Dc_creator( Node ): tag = u"dc:creator" +class Dc_date( Node ): tag = u"dc:date" +class Guid( Node ): tag = u"guid"