* Increasing after_login max string size from 100 to 1000 to accomodate larger URLs.
* controller.Notebooks now takes (and stores) an https_url constructor parameter. * New controller.Notebooks.updates() method to produce an updates RSS feed for a particular notebook. * New controller.Notebooks.get_update_link() method to make a brief page with just a link for an updated note, referred to by the feed. * Implemented views for the new RSS feed. * Fixed bug in Rss_item's guid that caused newlines to be inserted before and after long URLs. * Still need to unit test new controller code.
This commit is contained in:
parent
d3dce6f775
commit
b316b2f4a3
|
@ -18,6 +18,8 @@ from view.Json import Json
|
|||
from view.Html_file import Html_file
|
||||
from view.Note_tree_area import Note_tree_area
|
||||
from view.Notebook_rss import Notebook_rss
|
||||
from view.Updates_rss import Updates_rss
|
||||
from view.Update_link_page import Update_link_page
|
||||
|
||||
|
||||
class Notebooks( object ):
|
||||
|
@ -28,7 +30,7 @@ class Notebooks( object ):
|
|||
"""
|
||||
Controller for dealing with notebooks and their notes, corresponding to the "/notebooks" URL.
|
||||
"""
|
||||
def __init__( self, database, users, files ):
|
||||
def __init__( self, database, users, files, https_url ):
|
||||
"""
|
||||
Create a new Notebooks object.
|
||||
|
||||
|
@ -39,11 +41,14 @@ class Notebooks( object ):
|
|||
@type files: controller.Files
|
||||
@param files: controller for all uploaded files, used here for deleting files that are no longer
|
||||
referenced within saved notes
|
||||
@type https_url: unicode
|
||||
@param https_url: base URL to use for SSL http requests, or an empty string
|
||||
@return: newly constructed Notebooks
|
||||
"""
|
||||
self.__database = database
|
||||
self.__users = users
|
||||
self.__files = files
|
||||
self.__https_url = https_url
|
||||
|
||||
@expose( view = Main_page, rss = Notebook_rss )
|
||||
@strongly_expire
|
||||
|
@ -204,6 +209,70 @@ class Notebooks( object ):
|
|||
invites = invites or [],
|
||||
)
|
||||
|
||||
@expose( view = None, rss = Updates_rss )
|
||||
@strongly_expire
|
||||
@end_transaction
|
||||
@validate(
|
||||
notebook_id = Valid_id(),
|
||||
notebook_name = Valid_string(),
|
||||
)
|
||||
def updates( self, notebook_id, notebook_name ):
|
||||
"""
|
||||
Provide the information necessary to display an updated notes RSS feed for the given notebook.
|
||||
This method does not require any sort of login.
|
||||
|
||||
@type notebook_id: unicode
|
||||
@param notebook_id: id of the notebook to provide updates for
|
||||
@type notebook_name: unicode
|
||||
@param notebook_name: name of the notebook to include in the RSS feed
|
||||
@rtype: unicode
|
||||
@return: rendered RSS feed
|
||||
"""
|
||||
notebook = self.__database.load( Notebook, notebook_id )
|
||||
if not notebook:
|
||||
raise Access_error()
|
||||
|
||||
recent_notes = self.__database.select_many( Note, notebook.sql_load_notes( start = 0, count = 10 ) )
|
||||
|
||||
return dict(
|
||||
recent_notes = [ ( note.object_id, note.revision ) for note in recent_notes ],
|
||||
notebook_id = notebook_id,
|
||||
notebook_name = notebook_name,
|
||||
https_url = self.__https_url,
|
||||
)
|
||||
|
||||
@expose( view = Update_link_page )
|
||||
@strongly_expire
|
||||
@end_transaction
|
||||
@validate(
|
||||
notebook_id = Valid_id(),
|
||||
notebook_name = Valid_string(),
|
||||
note_id = Valid_id(),
|
||||
revision = Valid_revision(),
|
||||
)
|
||||
def get_update_link( self, notebook_id, notebook_name, note_id, revision ):
|
||||
"""
|
||||
Provide the information necessary to display a link to an updated note. This method does not
|
||||
require any sort of login.
|
||||
|
||||
@type notebook_id: unicode
|
||||
@param notebook_id: id of the notebook the note is in
|
||||
@type notebook_name: unicode
|
||||
@param notebook_name: name of the notebook
|
||||
@type note_id: unicode
|
||||
@param note_id: id of the note to link to
|
||||
@type revision: unicode
|
||||
@param revision: ignored; present so RSS feed readers distinguish between different revisions
|
||||
@rtype: unicode
|
||||
@return: rendered HTML page
|
||||
"""
|
||||
return dict(
|
||||
notebook_id = notebook_id,
|
||||
notebook_name = notebook_name,
|
||||
note_id = note_id,
|
||||
https_url = self.__https_url,
|
||||
)
|
||||
|
||||
@expose( view = Json )
|
||||
@strongly_expire
|
||||
@end_transaction
|
||||
|
|
|
@ -46,7 +46,7 @@ class Root( object ):
|
|||
settings[ u"global" ].get( u"luminotes.rate_plans", [] ),
|
||||
)
|
||||
self.__files = Files( database, self.__users )
|
||||
self.__notebooks = Notebooks( database, self.__users, self.__files )
|
||||
self.__notebooks = Notebooks( database, self.__users, self.__files, settings[ u"global" ].get( u"luminotes.https_url", u"" ) )
|
||||
self.__suppress_exceptions = suppress_exceptions # used for unit tests
|
||||
|
||||
@expose( Main_page )
|
||||
|
@ -55,7 +55,7 @@ class Root( object ):
|
|||
@validate(
|
||||
note_title = unicode,
|
||||
invite_id = Valid_id( none_okay = True ),
|
||||
after_login = Valid_string( min = 0, max = 100 ),
|
||||
after_login = Valid_string( min = 0, max = 1000 ),
|
||||
plan = Valid_int( none_okay = True ),
|
||||
user_id = Valid_id( none_okay = True ),
|
||||
)
|
||||
|
|
|
@ -407,7 +407,7 @@ class Users( object ):
|
|||
password = Valid_string( min = 1, max = 30 ),
|
||||
login_button = unicode,
|
||||
invite_id = Valid_id( none_okay = True ),
|
||||
after_login = Valid_string( min = 0, max = 100 ),
|
||||
after_login = Valid_string( min = 0, max = 1000 ),
|
||||
)
|
||||
def login( self, username, password, login_button, invite_id = None, after_login = None ):
|
||||
"""
|
||||
|
|
|
@ -9,5 +9,7 @@ class Rss_item( Item ):
|
|||
Link( link ),
|
||||
Description( description ),
|
||||
Dc_date( date ),
|
||||
Guid( guid ),
|
||||
# if we don't set the separator to empty, Node inserts newlines when the guid gets too long.
|
||||
# newlines in guids make Thunderbird angry
|
||||
Guid( guid, separator = u"" ),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
from Tags import Html, Head, Title, Body, A
|
||||
|
||||
|
||||
class Update_link_page( Html ):
|
||||
def __init__( self, notebook_id, notebook_name, note_id, https_url ):
|
||||
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_id
|
||||
|
||||
notebook_path = https_url + notebook_path
|
||||
|
||||
Html.__init__(
|
||||
self,
|
||||
Head(
|
||||
Title( "Note updated" ),
|
||||
),
|
||||
Body(
|
||||
u"A note in ",
|
||||
A( u"this notebook", href = notebook_path ),
|
||||
u"has been updated.",
|
||||
A( u"View the note.", href = u"%s?note_id=%s" % ( notebook_path, note_id ) ),
|
||||
),
|
||||
)
|
|
@ -0,0 +1,49 @@
|
|||
import cgi
|
||||
from urllib import urlencode
|
||||
from Rss_channel import Rss_channel
|
||||
from Rss_item import Rss_item
|
||||
|
||||
|
||||
class Updates_rss( Rss_channel ):
|
||||
def __init__(
|
||||
self,
|
||||
recent_notes,
|
||||
notebook_id,
|
||||
notebook_name,
|
||||
https_url,
|
||||
):
|
||||
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_id
|
||||
|
||||
notebook_path = https_url + notebook_path
|
||||
|
||||
Rss_channel.__init__(
|
||||
self,
|
||||
cgi.escape( notebook_name ),
|
||||
notebook_path,
|
||||
u"Luminotes notebook",
|
||||
[ Rss_item(
|
||||
title = u"Note updated",
|
||||
link = self.note_link( notebook_id, notebook_name, note_id, revision, https_url ),
|
||||
description = cgi.escape( u'A note in <a href="%s">this notebook</a> has been updated. <a href="%s?note_id=%s">View the note.</a>' % ( notebook_path, notebook_path, note_id ) ),
|
||||
date = revision.strftime( "%Y-%m-%dT%H:%M:%SZ" ),
|
||||
guid = self.note_link( notebook_id, notebook_name, note_id, revision, https_url ),
|
||||
) for ( note_id, revision ) in recent_notes ],
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def note_link( notebook_id, notebook_name, note_id, revision, https_url ):
|
||||
query = urlencode( [
|
||||
( u"notebook_id", notebook_id ),
|
||||
( u"notebook_name", notebook_name ),
|
||||
( u"note_id", note_id ),
|
||||
( u"revision", unicode( revision ) ),
|
||||
] )
|
||||
|
||||
return cgi.escape( u"%s/notebooks/get_update_link?%s" % ( https_url, query ) )
|
Reference in New Issue