Browse Source

Basic rss feed for blog.

Dan Helfman 11 years ago
parent
commit
f2721be076
8 changed files with 134 additions and 5 deletions
  1. 10
    2
      controller/Root.py
  2. 18
    0
      controller/test/Test_root.py
  3. 11
    1
      view/Link_area.py
  4. 3
    2
      view/Main_page.py
  5. 47
    0
      view/Notebook_rss.py
  6. 19
    0
      view/Rss_channel.py
  7. 13
    0
      view/Rss_item.py
  8. 13
    0
      view/Rss_tags.py

+ 10
- 2
controller/Root.py View File

@@ -10,6 +10,7 @@ from model.Note import Note
10 10
 from model.Notebook import Notebook
11 11
 from model.User import User
12 12
 from view.Main_page import Main_page
13
+from view.Notebook_rss import Notebook_rss
13 14
 from view.Json import Json
14 15
 from view.Error_page import Error_page
15 16
 from view.Not_found_page import Not_found_page
@@ -111,14 +112,15 @@ class Root( object ):
111 112
 
112 113
     return result
113 114
 
114
-  @expose( view = Main_page )
115
+  @expose( view = Main_page, rss = Notebook_rss )
115 116
   @grab_user_id
116 117
   @validate(
117 118
     start = Valid_int( min = 0 ),
118 119
     count = Valid_int( min = 1, max = 50 ),
120
+    note_id = Valid_id( none_okay = True ),
119 121
     user_id = Valid_id( none_okay = True ),
120 122
   )
121
-  def blog( self, start = 0, count = 3, user_id = None ):
123
+  def blog( self, start = 0, count = 5, note_id = None, user_id = None ):
122 124
     """
123 125
     Provide the information necessary to display the blog notebook with notes in reverse
124 126
     chronological order.
@@ -136,6 +138,12 @@ class Root( object ):
136 138
 
137 139
     result.update( self.__notebooks.load_recent_notes( blog_notebooks[ 0 ].object_id, start, count, user_id ) )
138 140
 
141
+    # if a single note was requested, just return that one note
142
+    if note_id:
143
+      result[ "notes" ] = [ note for note in result[ "notes" ] if note.object_id == note_id ]
144
+
145
+    result[ "http_url" ] = self.__settings[ u"global" ].get( u"luminotes.http_url", u"" )
146
+
139 147
     return result
140 148
 
141 149
   @expose( view = Main_page )

+ 18
- 0
controller/test/Test_root.py View File

@@ -124,6 +124,23 @@ class Test_root( Test_controller ):
124 124
     )
125 125
 
126 126
     assert result
127
+    assert u"error" not in result
128
+
129
+  def test_blog_with_note_id( self ):
130
+    result = self.http_get(
131
+      "/blog?note_id=%s" % self.blog_note.object_id,
132
+    )
133
+
134
+    assert result
135
+    assert u"error" not in result
136
+
137
+  def test_blog_rss( self ):
138
+    result = self.http_get(
139
+      "/blog?rss",
140
+    )
141
+
142
+    assert result
143
+    assert u"error" not in result
127 144
 
128 145
   def test_guide( self ):
129 146
     result = self.http_get(
@@ -131,6 +148,7 @@ class Test_root( Test_controller ):
131 148
     )
132 149
 
133 150
     assert result
151
+    assert u"error" not in result
134 152
 
135 153
   def test_next_id( self ):
136 154
     result = self.http_get( "/next_id" )

+ 11
- 1
view/Link_area.py View File

@@ -3,7 +3,7 @@ from Rounded_div import Rounded_div
3 3
 
4 4
 
5 5
 class Link_area( Div ):
6
-  def __init__( self, notebooks, notebook, total_notes_count, parent_id ):
6
+  def __init__( self, notebooks, notebook, total_notes_count, parent_id, notebook_path ):
7 7
     linked_notebooks = [ nb for nb in notebooks if nb.read_write and nb.name not in ( u"trash" ) ]
8 8
 
9 9
     Div.__init__(
@@ -34,6 +34,16 @@ class Link_area( Div ):
34 34
           class_ = u"link_area_item",
35 35
         ) or None,
36 36
 
37
+        ( notebook.name == u"Luminotes blog" ) and Div (
38
+          A(
39
+            u"subscribe to rss",
40
+            href = u"%s?rss" % notebook_path,
41
+            id = u"rss link",
42
+            title = u"Subscribe to the RSS feed for the Luminotes blog.",
43
+          ),
44
+          class_ = u"link_area_item",
45
+        ) or None,
46
+
37 47
         notebook.read_write and Span(
38 48
           notebook.trash_id and Div(
39 49
             A(

+ 3
- 2
view/Main_page.py View File

@@ -25,6 +25,7 @@ class Main_page( Page ):
25 25
     note_read_write = True,
26 26
     start = None,
27 27
     count = None,
28
+    http_url = None,
28 29
   ):
29 30
     startup_note_ids = [ startup_note.object_id for startup_note in startup_notes ]
30 31
 
@@ -93,7 +94,7 @@ class Main_page( Page ):
93 94
           Toolbar( hide_toolbar = not notebook.read_write ),
94 95
           id = u"toolbar_area",
95 96
         ),
96
-        Link_area( notebooks, notebook, total_notes_count, parent_id ),
97
+        Link_area( notebooks, notebook, total_notes_count, parent_id, notebook_path ),
97 98
         Div(
98 99
           Div(
99 100
             Div(
@@ -146,7 +147,7 @@ class Main_page( Page ):
146 147
                 type = u"text/javascript",
147 148
               ),
148 149
               # make page navigation for those notebooks that require it (such as the blog)
149
-              ( start is not None and count is not None ) and Div(
150
+              ( start is not None and count is not None and len( notes ) > 1 ) and Div(
150 151
                 ( start > 0 ) and Div( A(
151 152
                   u"previous page",
152 153
                   href = "%s?start=%d&count=%d" % ( notebook_path, max( start - count, 0 ), count ),

+ 47
- 0
view/Notebook_rss.py View File

@@ -0,0 +1,47 @@
1
+import cgi
2
+from Rss_channel import Rss_channel
3
+from Rss_item import Rss_item
4
+
5
+
6
+class Notebook_rss( Rss_channel ):
7
+  def __init__(
8
+    self,
9
+    user,
10
+    rate_plan,
11
+    notebooks,
12
+    notebook,
13
+    parent_id = None,
14
+    login_url = None,
15
+    logout_url = None,
16
+    startup_notes = None,
17
+    total_notes_count = None,
18
+    notes = None,
19
+    note_read_write = True,
20
+    start = None,
21
+    count = None,
22
+    http_url = u"",
23
+  ):
24
+    if notebook.name == u"Luminotes":
25
+      notebook_path = u"/"
26
+    elif notebook.name == u"Luminotes user guide":
27
+      notebook_path = u"/guide"
28
+    elif notebook.name == u"Luminotes blog":
29
+      notebook_path = u"/blog"
30
+    else:
31
+      notebook_path = u"/notebooks/%s" % notebook.object_id
32
+
33
+    notebook_path = http_url + notebook_path
34
+
35
+    Rss_channel.__init__(
36
+      self,
37
+      notebook.name,
38
+      notebook_path,
39
+      notebook.name,
40
+      [ Rss_item(
41
+        title = cgi.escape( note.title ),
42
+        link = u"%s?note_id=%s" % ( notebook_path, note.object_id ),
43
+        description = cgi.escape( note.contents ),
44
+        date = note.creation.strftime( "%Y-%m-%dT%H:%M:%SZ" ),
45
+        guid = u"%s?note_id=%s" % ( notebook_path, note.object_id ),
46
+      ) for note in notes ],
47
+    )

+ 19
- 0
view/Rss_channel.py View File

@@ -0,0 +1,19 @@
1
+from Rss_tags import Rss, Channel, Title, Link, Description, Language
2
+
3
+
4
+class Rss_channel( Rss ):
5
+  MAX_ITEMS = 20
6
+
7
+  def __init__( self, title, link, description, rss_items, language = None ):
8
+    Rss.__init__(
9
+      self,
10
+      Channel(
11
+        Title( u"%s" % title ),
12
+        Link( link ),
13
+        Description( description ),
14
+        Language( language or u"en-us" ),
15
+        rss_items[ : self.MAX_ITEMS ],
16
+      ),
17
+      version = u"2.0",
18
+      xmlns_dc = u"http://purl.org/dc/elements/1.1/",
19
+    )

+ 13
- 0
view/Rss_item.py View File

@@ -0,0 +1,13 @@
1
+from Rss_tags import Item, Title, Link, Description, Dc_date, Dc_creator, Guid
2
+
3
+
4
+class Rss_item( Item ):
5
+  def __init__( self, title, link, description, date, guid ):
6
+    Item.__init__(
7
+      self,
8
+      Title( title ),
9
+      Link( link ),
10
+      Description( description ),
11
+      Dc_date( date ),
12
+      Guid( guid ),
13
+    )

+ 13
- 0
view/Rss_tags.py View File

@@ -0,0 +1,13 @@
1
+from Node import Node
2
+
3
+
4
+class Rss( Node ): tag = u"rss"
5
+class Channel( Node ): tag = u"channel"
6
+class Title( Node ): tag = u"title"
7
+class Link( Node ): tag = u"link"
8
+class Description( Node ): tag = u"description"
9
+class Language( Node ): tag = u"language"
10
+class Item( Node ): tag = u"item"
11
+class Dc_creator( Node ): tag = u"dc:creator"
12
+class Dc_date( Node ): tag = u"dc:date"
13
+class Guid( Node ): tag = u"guid"

Loading…
Cancel
Save