Merge lp:~flacoste/launchpad/bug-129943 into lp:launchpad

Proposed by Francis J. Lacoste
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 11192
Proposed branch: lp:~flacoste/launchpad/bug-129943
Merge into: lp:launchpad
Diff against target: 633 lines (+388/-67)
11 files modified
configs/development/launchpad.conf (+1/-1)
configs/testrunner/launchpad-lazr.conf (+3/-0)
lib/canonical/config/schema-lazr.conf (+5/-0)
lib/canonical/launchpad/ftests/googlesearches/blog.launchpad.net-feed.xml (+266/-0)
lib/canonical/launchpad/ftests/googlesearches/mapping.txt (+2/-0)
lib/lp/app/browser/root.py (+47/-9)
lib/lp/app/browser/tests/test_launchpadroot.py (+4/-0)
lib/lp/app/stories/launchpad-root/front-pages.txt (+45/-30)
lib/lp/app/templates/root-index.pt (+13/-27)
setup.py (+1/-0)
versions.cfg (+1/-0)
To merge this branch: bzr merge lp:~flacoste/launchpad/bug-129943
Reviewer Review Type Date Requested Status
Matthew Revell (community) acceptance Approve
Robert Collins (community) Approve
Review via email: mp+30158@code.launchpad.net

Commit message

Automatically fetches the recent blog posts list from the blog RSS feed

Description of the change

  = Summary =

This fetches the recent blog posts from the blog site RSS feed.

== Pre-implementation notes ==

 * Discused requirements with mrevell

== Implementation details ==

 * I use urlfetch to retrieve the feed since that urllib2 wrapper supports
   timeout.
 * I use the feedparser module to do the RSS parsing.
 * I use memcached so that we don't fetch / parse the results more than once
   an hour.

Matt told me to use the general feed for now and I used 6 as the number of
posts to display since that's what we are using now.

The description returned by the feed is longer than what we have now on the
front page. I don't know if we can fix this on the blog side.

You can find a screenshot of what it looks like at:
http://people.canonical.com/~flacoste/automatic-recent-blogs.png

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

8 - address 8089
9 + address 8088

seems unrelated?

While you're there -
444 +
445 The homepage looks different when the use is logged in:
..................................................^r

Lastly, python-feedparser is a pretty static dependency, please consider using the launchpad-dependencies for it rather than buildout - its less unchanging stuff to be copied to the appservers on every deployment.

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

Tweaking to needsfixing - sorry for the noise. (the port number needs fixing or explaining, the rest is optional-but-preferred :).

review: Needs Fixing
Revision history for this message
Francis J. Lacoste (flacoste) wrote :

Thanks for the review.

I've fixed the typo.

The port number was changed because 8089 conflicts with Banshee DAAP locally. Since it might burn other folks too, I decided to commit it.

Even though python-feedparser is a pretty static dependancy, I'd really not want to block on a l-d-d update to land this branch. If you insist, I could add it to the launchpad-dependencies, so that the next deployment of it, would pull it off and use it instead of the one in the download-cache. I would not ask LOSA to go to the trouble of building new buildbot images and deploy these two packages across all app servers for that dependency.

Revision history for this message
Robert Collins (lifeless) wrote :

> Even though python-feedparser is a pretty static dependancy, I'd really not want to block on a l-d-d update to land this branch. If you insist, I could add it to the launchpad-dependencies, so that the next deployment of it, would pull it off and use it instead of the one in the download-cache. I would not ask LOSA to go to the trouble of building new buildbot images and deploy these two packages across all app servers for that dependency.

I'm fine with not blocking.

If we need new buildbot images when a standard packaged item is added
to the deps, thats a bug in our use of buildbot we should just fix. Is
that historical or current experience?

James and Tom have indicated in the past that new deps in the packages
are trivial for them to accomodate when they are of standard packages,
so I wouldn't expect any difficulty in having it deployed promptly.

But again, I'm fine with not blocking, doing the l-prod-d dependency
change and when that has been fully actioned dropping the buildout
stanza.

Revision history for this message
Francis J. Lacoste (flacoste) wrote :

Actually, after asking Gary, that might be historical. It seems we do update package dependencies at the beginning of every test run.

Once the package is installed, we don't remove the buildout stanza as this is still a dependency of the system. buildout will use the system-installed version to resolve the dependency automatically instead of building an eggs from the source distribution in the download-cache.

Cheers

Revision history for this message
Robert Collins (lifeless) wrote :

\o/

review: Approve
Revision history for this message
Matthew Revell (matthew.revell) wrote :

As discussed on the phone, I'm happy with using the main blog feed and also with keeping a static story about the open sourcing until we redesign the home page.

review: Approve (acceptance)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configs/development/launchpad.conf'
2--- configs/development/launchpad.conf 2010-03-02 07:33:03 +0000
3+++ configs/development/launchpad.conf 2010-07-21 18:54:52 +0000
4@@ -19,7 +19,7 @@
5 # an exception, Zope will drop into pdb at the point of the exception.
6 <server>
7 type PostmortemDebuggingHTTP
8- address 8089
9+ address 8088
10 </server>
11
12 <server>
13
14=== modified file 'configs/testrunner/launchpad-lazr.conf'
15--- configs/testrunner/launchpad-lazr.conf 2010-06-08 15:13:20 +0000
16+++ configs/testrunner/launchpad-lazr.conf 2010-07-21 18:54:52 +0000
17@@ -132,6 +132,9 @@
18 max_attachment_size: 1024
19 geoip_database: /usr/share/GeoIP/GeoLiteCity.dat
20 logparser_max_parsed_lines: 100000
21+# We use the stub Google Service here which maps URL fragment to
22+# to static content
23+homepage_recent_posts_feed: http://launchpad.dev:8092/blog-feed
24
25 [launchpad_session]
26 cookie: launchpad_tests
27
28=== modified file 'lib/canonical/config/schema-lazr.conf'
29--- lib/canonical/config/schema-lazr.conf 2010-07-14 15:37:51 +0000
30+++ lib/canonical/config/schema-lazr.conf 2010-07-21 18:54:52 +0000
31@@ -1138,6 +1138,11 @@
32 # log parser. The default value of None means there is no maximum.
33 logparser_max_parsed_lines: None
34
35+# The URL to the RSS feed that will be displayed on the front page
36+homepage_recent_posts_feed: http://blog.launchpad.net/feed
37+
38+# The number of items to display:
39+homepage_recent_posts_count: 6
40
41 [launchpad_session]
42 # The hostname where the session database is located.
43
44=== added file 'lib/canonical/launchpad/ftests/googlesearches/blog.launchpad.net-feed.xml'
45--- lib/canonical/launchpad/ftests/googlesearches/blog.launchpad.net-feed.xml 1970-01-01 00:00:00 +0000
46+++ lib/canonical/launchpad/ftests/googlesearches/blog.launchpad.net-feed.xml 2010-07-21 18:54:52 +0000
47@@ -0,0 +1,266 @@
48+<?xml version="1.0" encoding="UTF-8"?>
49+<rss version="2.0"
50+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
51+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
52+ xmlns:dc="http://purl.org/dc/elements/1.1/"
53+ xmlns:atom="http://www.w3.org/2005/Atom"
54+ xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
55+ xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
56+ >
57+
58+<channel>
59+ <title>Launchpad blog</title>
60+ <atom:link href="http://blog.launchpad.net/feed" rel="self" type="application/rss+xml" />
61+ <link>http://blog.launchpad.net</link>
62+ <description>Thoughts from the Launchpad team</description>
63+ <lastBuildDate>Fri, 16 Jul 2010 13:02:58 +0000</lastBuildDate>
64+ <generator>http://wordpress.org/?v=2.8.4</generator>
65+ <language>en</language>
66+ <sy:updatePeriod>hourly</sy:updatePeriod>
67+ <sy:updateFrequency>1</sy:updateFrequency>
68+ <item>
69+ <title>Launchpad EPIC 2010 photo</title>
70+ <link>http://blog.launchpad.net/general/launchpad-epic-2010-photo</link>
71+ <comments>http://blog.launchpad.net/general/launchpad-epic-2010-photo#comments</comments>
72+ <pubDate>Fri, 16 Jul 2010 13:02:58 +0000</pubDate>
73+ <dc:creator>Matthew Revell</dc:creator>
74+ <category><![CDATA[General]]></category>
75+
76+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1631</guid>
77+ <description><![CDATA[The Launchpad and Bazaar teams have been in Prague this week. More on what we got done in later posts. For now, here&#8217;s a photo!
78+]]></description>
79+ <content:encoded><![CDATA[<p>The Launchpad and Bazaar teams have been in Prague this week. More on what we got done in later posts. For now, here&#8217;s a photo!<br />
80+<div id="attachment_1632" class="wp-caption alignnone" style="width: 730px"><img src="/wp-content/uploads/2010/07/epic2010-team-photo.JPG" alt="The Launchpad and Bazaar teams in Prague" title="epic2010-team-photo" width="720" height="479" class="size-full wp-image-1632" /><p class="wp-caption-text">The Launchpad and Bazaar teams in Prague</p></div></p>
81+]]></content:encoded>
82+ <wfw:commentRss>http://blog.launchpad.net/general/launchpad-epic-2010-photo/feed</wfw:commentRss>
83+ <slash:comments>0</slash:comments>
84+ </item>
85+ <item>
86+ <title>Three tips for faster launchpadlib api clients</title>
87+ <link>http://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients</link>
88+ <comments>http://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients#comments</comments>
89+ <pubDate>Wed, 14 Jul 2010 13:30:04 +0000</pubDate>
90+ <dc:creator>Martin Pool</dc:creator>
91+ <category><![CDATA[API]]></category>
92+ <category><![CDATA[clients]]></category>
93+ <category><![CDATA[performance]]></category>
94+ <category><![CDATA[tip]]></category>
95+
96+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1626</guid>
97+ <description><![CDATA[Three tips from Leonard&#8217;s lightning talk in Prague about writing faster Launchpadlib API clients:
98+1. Use the latest launchpadlib. It gets faster from one release to the next. (The versions in the current Ubuntu release should be fine; otherwise run from the branch or the latest tarball.)
99+2. Profile:
100+
101+ import httplib2
102+ [...]]]></description>
103+ <content:encoded><![CDATA[<p>Three tips from <a href="http://launchpad.net/~leonardr">Leonard&#8217;s</a> lightning talk in Prague about writing faster <a href="https://help.launchpad.net/API/launchpadlib#preview">Launchpadlib</a> API clients:</p>
104+<p><b>1. Use the latest launchpadlib.</b> It gets faster from one release to the next. (The versions in the current Ubuntu release should be fine; otherwise run from the <a href="https://code.edge.launchpad.net/~lazr-developers/launchpadlib/trunk">branch</a> or the latest <a href="https://launchpad.net/launchpadlib/+download">tarball</a>.)</p>
105+<p><b>2. Profile:</b></p>
106+<pre>
107+ import httplib2
108+ httplib2.debuglevel = 1
109+</pre>
110+<p>will show each http request and response, so that you can see what&#8217;s taking time.</p>
111+<p><b>3. Fetch objects only once:</b></p>
112+<p>Don&#8217;t do this:</p>
113+<pre>
114+ if bug.person is not None:
115+ print bug.person.name
116+</pre>
117+<p>instead</p>
118+<pre>
119+ p = bug.person
120+ if p is not None:
121+ print p.name
122+</pre>
123+<p>In the first case, the client may fetch the Person object twice. (We may fix this in future.)</p>
124+]]></content:encoded>
125+ <wfw:commentRss>http://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients/feed</wfw:commentRss>
126+ <slash:comments>5</slash:comments>
127+ </item>
128+ <item>
129+ <title>New Launchpad Bugs Status: Opinion</title>
130+ <link>http://blog.launchpad.net/bug-tracking/new-bugs-status-opinion</link>
131+ <comments>http://blog.launchpad.net/bug-tracking/new-bugs-status-opinion#comments</comments>
132+ <pubDate>Wed, 07 Jul 2010 08:18:33 +0000</pubDate>
133+ <dc:creator>Deryck Hodge</dc:creator>
134+ <category><![CDATA[Bug Tracking]]></category>
135+
136+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1613</guid>
137+ <description><![CDATA[Many different types of information are stored in bug reports in Launchpad.
138+Some are actual defects, some are feature requests, some are general issues, and so on.  It is not uncommon on Launchpad to have a bug that deals with an issue that a developer cannot resolve.  In Launchpad, we offer a couple of bug [...]]]></description>
139+ <content:encoded><![CDATA[<p>Many different types of information are stored in bug reports in Launchpad. </p>
140+<p>Some are actual defects, some are feature requests, some are general issues, and so on.  It is not uncommon on Launchpad to have a bug that deals with an issue that a developer cannot resolve.  In Launchpad, we offer a couple of bug statuses that allow a developer to close a bug report without actually doing what is requested in the report: these are <em>Won&#8217;t Fix</em> and <em>Invalid</em>. </p>
141+<p>Often, though, there may still be a discussion. <em>Won&#8217;t Fix</em> and <em>Invalid</em> are useful for the developer, and the project, to know that they don&#8217;t need to schedule time for a fix. However, they can sometimes &mdash; rightly or wrongly &mdash; be seen as an attempt to close down to discussion.</p>
142+<p>We&#8217;ve just added a new bug status to Launchpad: <em>Opinion</em>. Now, this is a fairly momentous occasion; we hardly ever make changes to bug statuses because they, naturally, have a great impact on how you and others use Launchpad to track bugs. However, we feel it&#8217;s important to find a way to balance a project&#8217;s need for useful work planning with the need for intelligent and open discussion.</p>
143+<p><em>Opinion</em> says: there&#8217;s a difference of opinion around this bug and people are free to continue the discussion, but the project or package maintainers need to move to other work and are considering the issue closed.</p>
144+<p>Like I said, adding a new bug status to Launchpad is a big deal. So, we&#8217;re treating <em>Opinion</em> as an experiment. We&#8217;ll watch how it is used over the next three months and then we&#8217;ll decide if the status is proving useful and effective at closing bugs while leaving the discussion open.</p>
145+<p>I&#8217;d love to hear your views on this new status: leave a comment here, join us on the <a href="https://launchpad.net/~launchpad-users">launchpad-users</a> mailing list or <a href="https://launchpad.net/~deryck/+contactuser">mail me directly</a>.</p>
146+]]></content:encoded>
147+ <wfw:commentRss>http://blog.launchpad.net/bug-tracking/new-bugs-status-opinion/feed</wfw:commentRss>
148+ <slash:comments>4</slash:comments>
149+ </item>
150+ <item>
151+ <title>SFTP uploads to PPAs!</title>
152+ <link>http://blog.launchpad.net/cool-new-stuff/sftp-uploads</link>
153+ <comments>http://blog.launchpad.net/cool-new-stuff/sftp-uploads#comments</comments>
154+ <pubDate>Wed, 07 Jul 2010 08:07:03 +0000</pubDate>
155+ <dc:creator>Matthew Revell</dc:creator>
156+ <category><![CDATA[Cool new stuff]]></category>
157+ <category><![CDATA[PPA]]></category>
158+
159+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1607</guid>
160+ <description><![CDATA[You can now use SFTP to upload source packages to your Personal Package Archive!
161+If you&#8217;re already familiar with uploading to a PPA, all you need to do is ensure your dput.cf includes the following:
162+
163+method = sftp
164+login = &#60;your Launchpad account name&#62;
165+
166+If you&#8217;re new to PPAs, but already know how to create packages for Ubuntu, take [...]]]></description>
167+ <content:encoded><![CDATA[<p>You can now use SFTP to upload source packages to your Personal Package Archive!</p>
168+<p>If you&#8217;re already familiar with uploading to a PPA, all you need to do is ensure your <code>dput.cf</code> includes the following:</p>
169+<p><code><br />
170+method = sftp<br />
171+login = &lt;your Launchpad account name&gt;<br />
172+</code></p>
173+<p>If you&#8217;re new to PPAs, but already know how to create packages for Ubuntu, <a href="https://help.launchpad.net/Packaging/PPA">take a look at our guide</a>.</p>
174+]]></content:encoded>
175+ <wfw:commentRss>http://blog.launchpad.net/cool-new-stuff/sftp-uploads/feed</wfw:commentRss>
176+ <slash:comments>4</slash:comments>
177+ </item>
178+ <item>
179+ <title>UPDATED: Launchpad read-only 23.00 UTC 6th July</title>
180+ <link>http://blog.launchpad.net/notifications/launchpad-read-only-23-00-utc-1st-july</link>
181+ <comments>http://blog.launchpad.net/notifications/launchpad-read-only-23-00-utc-1st-july#comments</comments>
182+ <pubDate>Mon, 28 Jun 2010 16:23:37 +0000</pubDate>
183+ <dc:creator>Matthew Revell</dc:creator>
184+ <category><![CDATA[Notifications]]></category>
185+
186+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1609</guid>
187+ <description><![CDATA[This replaces the previously announced period of unavailability for the 1st of July.
188+Launchpad&#8217;s web interface will be read-only, with other aspects offline, for around 90 minutes from 23.00 UTC on the 6th of July 2010.
189+This is to allow for the release of the latest Launchpad code.
190+Starts: 23.00 UTC 6th July 2010
191+Expected back online: 00.30 UTC [...]]]></description>
192+ <content:encoded><![CDATA[<p><strong>This replaces the previously announced period of unavailability for the 1st of July.</strong></p>
193+<p>Launchpad&#8217;s web interface will be read-only, with other aspects offline, for around 90 minutes from 23.00 UTC on the 6th of July 2010.</p>
194+<p>This is to allow for the release of the latest Launchpad code.</p>
195+<p><strong>Starts:</strong> 23.00 UTC 6th July 2010<br />
196+<strong>Expected back online:</strong> 00.30 UTC 7th July 2010</p>
197+]]></content:encoded>
198+ <wfw:commentRss>http://blog.launchpad.net/notifications/launchpad-read-only-23-00-utc-1st-july/feed</wfw:commentRss>
199+ <slash:comments>0</slash:comments>
200+ </item>
201+ <item>
202+ <title>Take the Launchpad user survey!</title>
203+ <link>http://blog.launchpad.net/general/take-the-launchpad-user-survey</link>
204+ <comments>http://blog.launchpad.net/general/take-the-launchpad-user-survey#comments</comments>
205+ <pubDate>Wed, 23 Jun 2010 12:26:00 +0000</pubDate>
206+ <dc:creator>Matthew Revell</dc:creator>
207+ <category><![CDATA[General]]></category>
208+
209+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1604</guid>
210+ <description><![CDATA[There are all sorts of different ways in which we in Canonical&#8217;s Launchpad team keep in touch with people who use Launchpad: informal conversations on IRC, attending Ubuntu Developer Summits, formal user research and so on.
211+We want to hear from as many people who use Launchpad as possible. To help get there, I&#8217;ve created a [...]]]></description>
212+ <content:encoded><![CDATA[<p>There are all sorts of different ways in which we in Canonical&#8217;s Launchpad team keep in touch with people who use Launchpad: informal conversations on IRC, attending Ubuntu Developer Summits, formal user research and so on.</p>
213+<p>We want to hear from as many people who use Launchpad as possible. To help get there, I&#8217;ve created a survey with five questions. Tell us what you like about Launchpad, what you don&#8217;t and what sort of work you do in Launchpad:</p>
214+<p><big><strong><a href="http://www.surveymonkey.com/s/launchpadsummer2010">Take the Launchpad user survey</a>!</strong></big></p>
215+]]></content:encoded>
216+ <wfw:commentRss>http://blog.launchpad.net/general/take-the-launchpad-user-survey/feed</wfw:commentRss>
217+ <slash:comments>1</slash:comments>
218+ </item>
219+ <item>
220+ <title>Meet Steve Kowalik</title>
221+ <link>http://blog.launchpad.net/meet-the-devs/meet-steve-kowalik</link>
222+ <comments>http://blog.launchpad.net/meet-the-devs/meet-steve-kowalik#comments</comments>
223+ <pubDate>Mon, 21 Jun 2010 16:22:33 +0000</pubDate>
224+ <dc:creator>Matthew Revell</dc:creator>
225+ <category><![CDATA[Meet the devs]]></category>
226+
227+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1597</guid>
228+ <description><![CDATA[Steve Kowalik recently joined the Soyuz part of the Launchpad team at Canonical, so I asked him the, by now familiar, questions!
229+Matthew: What were you doing before you joined the Launchpad team?
230+Steve: I worked on the Ubuntu Mobile team for 2.5 years before switching to the Launchpad team to work on Soyuz.
231+Matthew: Can we see [...]]]></description>
232+ <content:encoded><![CDATA[<p><a href="https://launchpad.net/~stevenk">Steve Kowalik</a> recently joined the Soyuz part of the Launchpad team at Canonical, so I asked him the, by now familiar, questions!</p>
233+<p><strong>Matthew: What were you doing before you joined the Launchpad team?</strong></p>
234+<p><strong>Steve:</strong> I worked on the Ubuntu Mobile team for 2.5 years before switching to the Launchpad team to work on Soyuz.</p>
235+<p><strong>Matthew: Can we see something that you&#8217;ve worked on from that time?</strong></p>
236+<p><strong>Steve:</strong> You sure can. The images and large parts of the integration work for Ubuntu Netbook Remix 9.04 and Ubuntu Netbook Edition 9.10 were done by me. I was also responsible for image builds for the three ARM sub-architectures for the 9.10 release.</p>
237+<p><strong>Matthew: Where do you work?</strong></p>
238+<p><strong>Steve:</strong> I work from my apartment in Sydney, Australia.</p>
239+<p><strong>Matthew: What can you see from your office window?</strong></p>
240+<p><strong>Steve:</strong> Another apartment block, so not the most glamorous of settings. From the other side of my apartment, I can see the local river. So it depends on the definition of office, if it&#8217;s my &#8220;office&#8221; or the balcony I work from on summer days.</p>
241+<p><strong>Matthew: What did you do before working at Canonical?</strong></p>
242+<p><strong>Steve:</strong> I worked at a company in Burwood, NSW specializing in satellite communications, and worked on supporting and developing their in-house Debian-derived distribution.</p>
243+<p><strong>Matthew: How did you get into free software?</strong></p>
244+<p><strong>Steve:</strong> I became interested in Linux when I was in high school, after I came across the term and researched it on the Internet. I started running it in 1999, and switched to Debian from Red Hat in 2000. I became a Debian Developer in 2001, and switched to Ubuntu in mid 2005.</p>
245+<p><strong>Matthew: What&#8217;s more important? Principle or pragmatism?</strong></p>
246+<p><strong>Steve:</strong> I believe pragmatism is more important, as it allows people to use hard data to define the problem or solution space, and work within its boundaries.</p>
247+<p><strong>Matthew: Do you/have you contribute(d) to any free software projects?</strong></p>
248+<p><strong>Steve:</strong> I&#8217;ve had a large number of patches and changes in Ubuntu, some in Debian, and I&#8217;ve written a Debian package checker from scratch, called Linda. I&#8217;ve been involved in free software for over ten years now. </p>
249+<p><strong>Matthew: Tell us something really cool about Launchpad that not enough people know about.</strong></p>
250+<p><strong>Steve:</strong> You can now upload packages to PPAs and Ubuntu via SFTP! As an added bonus, I wrote the support for it in Launchpad.</p>
251+<p><strong>Matthew: Is there anything in particular you plan to work on while you&#8217;re with Launchpad?</strong></p>
252+<p><strong>Steve:</strong> I plan on helping to make Soyuz more stable, more feature-ful and hopefully, faster.</p>
253+<p><strong>Matthew: Okay, <a href="https://launchpad.net/~kiko">Kiko</a>&#8217;s special question! You&#8217;re at your computer, you reach for your wallet: what are you most likely to be doing?</strong></p>
254+<p><strong>Steve:</strong> I&#8217;m either paying a bill, or buying something online.</p>
255+]]></content:encoded>
256+ <wfw:commentRss>http://blog.launchpad.net/meet-the-devs/meet-steve-kowalik/feed</wfw:commentRss>
257+ <slash:comments>0</slash:comments>
258+ </item>
259+ <item>
260+ <title>Faster pages</title>
261+ <link>http://blog.launchpad.net/general/faster-pages</link>
262+ <comments>http://blog.launchpad.net/general/faster-pages#comments</comments>
263+ <pubDate>Fri, 11 Jun 2010 15:15:43 +0000</pubDate>
264+ <dc:creator>Curtis Hovey</dc:creator>
265+ <category><![CDATA[General]]></category>
266+
267+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1561</guid>
268+ <description><![CDATA[I am happy to report that caching rules I put in place on many pages last week are effective. I did not want to announce that pages were faster until I could see read a week of oops reports to verify that the slow pages owned by the Launchpad registry team were no longer listed [...]]]></description>
269+ <content:encoded><![CDATA[<p>I am happy to report that caching rules I put in place on many pages last week are effective. I did not want to announce that pages were faster until I could see read a week of oops reports to verify that the slow pages owned by the Launchpad registry team were no longer listed as problems. I am honestly surprised that all the slow pages I changes are not listed. I expected to make a reduction in timeouts between 50% and 80%. This looks like a 100% success. I know it is not 100%, but I think this means that milestone, series, and project pages load quicker and you are seeing fewer timeouts.</p>
270+<p>Launchpad pages now have access to memcached to store fragments of pages. Parts of pages that are costly to generate are cached for minutes or hours depending on how often the data can change. In the case of distro series pages, architecture data changes every few months so the cache rules are 6 hours. Milestone pages were a challenge to cache. Active milestones cache bugs for 10 minutes, Inactive milestones cache for 3 hours. The milestone summary of statuses and assignments cache for 1 hour. If you do not know this, you may suspect there is a bug in launchpad, or wonder if you did not update a bug as you thought. We need a mechanism to expire change when data is changed.</p>
271+<p>We are now adding cache rules to other pages to improve page load times.</p>
272+]]></content:encoded>
273+ <wfw:commentRss>http://blog.launchpad.net/general/faster-pages/feed</wfw:commentRss>
274+ <slash:comments>4</slash:comments>
275+ </item>
276+ <item>
277+ <title>Change to 2nd June Launchpad read-only/down-time</title>
278+ <link>http://blog.launchpad.net/notifications/change-to-2nd-june-launchpad-read-onlydown-time</link>
279+ <comments>http://blog.launchpad.net/notifications/change-to-2nd-june-launchpad-read-onlydown-time#comments</comments>
280+ <pubDate>Tue, 01 Jun 2010 14:29:55 +0000</pubDate>
281+ <dc:creator>Matthew Revell</dc:creator>
282+ <category><![CDATA[Notifications]]></category>
283+
284+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1557</guid>
285+ <description><![CDATA[We&#8217;ve had to alter the times between which Launchpad&#8217;s web interface will be read-only, while everything else is offline, for the release of Launchpad 10.05.
286+New start time: 11.00 UTC 2nd June 2010
287+New end time: 14.00 UTC 2nd June 2010
288+]]></description>
289+ <content:encoded><![CDATA[<p>We&#8217;ve had to alter the times between which Launchpad&#8217;s web interface will be read-only, while everything else is offline, for the release of Launchpad 10.05.</p>
290+<p><strong>New start time:</strong> 11.00 UTC 2nd June 2010<br />
291+<strong>New end time:</strong> 14.00 UTC 2nd June 2010</p>
292+]]></content:encoded>
293+ <wfw:commentRss>http://blog.launchpad.net/notifications/change-to-2nd-june-launchpad-read-onlydown-time/feed</wfw:commentRss>
294+ <slash:comments>1</slash:comments>
295+ </item>
296+ <item>
297+ <title>UPDATED: Launchpad read-only 08.00-11.00 UTC 2nd June 2010</title>
298+ <link>http://blog.launchpad.net/notifications/launchpad-read-only-08-00-11-00-utc-2nd-june-2010</link>
299+ <comments>http://blog.launchpad.net/notifications/launchpad-read-only-08-00-11-00-utc-2nd-june-2010#comments</comments>
300+ <pubDate>Mon, 31 May 2010 15:28:13 +0000</pubDate>
301+ <dc:creator>Matthew Revell</dc:creator>
302+ <category><![CDATA[Notifications]]></category>
303+
304+ <guid isPermaLink="false">http://blog.launchpad.net/?p=1553</guid>
305+ <description><![CDATA[See our new post on this.
306+]]></description>
307+ <content:encoded><![CDATA[<p><a href="http://blog.launchpad.net/notifications/change-to-2nd-june-launchpad-read-onlydown-time">See our new post on this</a>.</p>
308+]]></content:encoded>
309+ <wfw:commentRss>http://blog.launchpad.net/notifications/launchpad-read-only-08-00-11-00-utc-2nd-june-2010/feed</wfw:commentRss>
310+ <slash:comments>0</slash:comments>
311+ </item>
312+ </channel>
313+</rss>
314
315=== modified file 'lib/canonical/launchpad/ftests/googlesearches/mapping.txt'
316--- lib/canonical/launchpad/ftests/googlesearches/mapping.txt 2009-06-16 20:04:54 +0000
317+++ lib/canonical/launchpad/ftests/googlesearches/mapping.txt 2010-07-21 18:54:52 +0000
318@@ -20,3 +20,5 @@
319
320 /cse?client=google-csbe&cx=ABCDEF2323&ie=utf8&num=20&oe=utf8&output=xml_no_dtd&q=no-meaningful&start=0 googlesearchservice-no-meaningful-results.xml
321
322+# This stub service is also used to impersonate the Blog feed
323+/blog-feed blog.launchpad.net-feed.xml
324
325=== modified file 'lib/lp/app/browser/root.py'
326--- lib/lp/app/browser/root.py 2010-04-19 14:47:49 +0000
327+++ lib/lp/app/browser/root.py 2010-07-21 18:54:52 +0000
328@@ -1,6 +1,5 @@
329 # Copyright 2009 Canonical Ltd. This software is licensed under the
330 # GNU Affero General Public License version 3 (see the file LICENSE).
331-
332 """Browser code for the Launchpad root page."""
333
334 __metaclass__ = type
335@@ -10,6 +9,7 @@
336 ]
337
338
339+import feedparser
340 import re
341 import sys
342 import time
343@@ -21,30 +21,33 @@
344
345
346 from canonical.cachedproperty import cachedproperty
347-from lp.registry.browser.announcement import HasAnnouncementsView
348+from canonical.config import config
349 from canonical.launchpad.interfaces.launchpadstatistic import (
350 ILaunchpadStatisticSet)
351+from canonical.lazr.timeout import urlfetch
352 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
353 from canonical.launchpad.webapp.publisher import canonical_url
354-from lp.code.interfaces.branchcollection import IAllBranches
355-from lp.bugs.interfaces.bug import IBugSet
356 from canonical.launchpad.interfaces.launchpad import ILaunchpadSearch
357-from lp.registry.interfaces.pillar import IPillarNameSet
358-from lp.registry.interfaces.person import IPersonSet
359-from lp.registry.interfaces.product import IProductSet
360 from canonical.launchpad.interfaces.searchservice import (
361 GoogleResponseError, ISearchService)
362-from lp.blueprints.interfaces.specification import ISpecificationSet
363 from canonical.launchpad.validators.name import sanitize_name
364 from canonical.launchpad.webapp import (
365 action, LaunchpadFormView, LaunchpadView, safe_action)
366 from canonical.launchpad.webapp.authorization import check_permission
367 from canonical.launchpad.webapp.batching import BatchNavigator
368 from canonical.launchpad.webapp.interfaces import NotFoundError
369+from canonical.launchpad.webapp.vhosts import allvhosts
370+
371 from lazr.batchnavigator.z3batching import batch
372-from canonical.launchpad.webapp.vhosts import allvhosts
373
374 from lp.answers.interfaces.questioncollection import IQuestionSet
375+from lp.blueprints.interfaces.specification import ISpecificationSet
376+from lp.code.interfaces.branchcollection import IAllBranches
377+from lp.bugs.interfaces.bug import IBugSet
378+from lp.registry.browser.announcement import HasAnnouncementsView
379+from lp.registry.interfaces.person import IPersonSet
380+from lp.registry.interfaces.pillar import IPillarNameSet
381+from lp.registry.interfaces.product import IProductSet
382
383
384 shipit_faq_url = 'http://www.ubuntu.com/getubuntu/shipit-faq'
385@@ -129,6 +132,41 @@
386 """The total blueprint count in all of Launchpad."""
387 return getUtility(ILaunchpadStatisticSet).value('question_count')
388
389+ def getRecentBlogPosts(self):
390+ """Return the parsed feed of the most recent blog posts.
391+
392+ It returns a list of dict with keys title, description, link and date.
393+
394+ The date is formatted and the description which may contain HTML is
395+ sanitized.
396+
397+ The number of blog posts to display is controlled through
398+ launchpad.homepage_recent_posts_count. The posts are fetched
399+ from the feed specified in launchpad.homepage_recent_posts_feed.
400+
401+ Since the feed is parsed everytime, the template should cache this
402+ through memcached.
403+
404+ FeedParser takes care of sanitizing the HTML contained in the feed.
405+ """
406+ # Use urlfetch which supports timeout
407+ try:
408+ data = urlfetch(config.launchpad.homepage_recent_posts_feed)
409+ except IOError:
410+ return []
411+ feed = feedparser.parse(data)
412+ posts = []
413+ max_count = config.launchpad.homepage_recent_posts_count
414+ # FeedParser takes care of HTML sanitisation.
415+ for entry in feed.entries[:max_count]:
416+ posts.append({
417+ 'title': entry.title,
418+ 'description': entry.description,
419+ 'link': entry.link,
420+ 'date': time.strftime('%d %b %Y', entry.updated_parsed),
421+ })
422+ return posts
423+
424
425 class LaunchpadSearchFormView(LaunchpadView):
426 """A view to display the global search form in any page."""
427
428=== modified file 'lib/lp/app/browser/tests/test_launchpadroot.py'
429--- lib/lp/app/browser/tests/test_launchpadroot.py 2010-07-18 00:23:02 +0000
430+++ lib/lp/app/browser/tests/test_launchpadroot.py 2010-07-21 18:54:52 +0000
431@@ -5,6 +5,7 @@
432
433 __metaclass__ = type
434
435+
436 from BeautifulSoup import BeautifulSoup, SoupStrainer
437
438 from zope.component import getUtility
439@@ -66,6 +67,9 @@
440 self.setUpRegistryExpert()
441 view = create_initialized_view(
442 self.root, 'index.html', principal=self.expert)
443+ # Stub out the getRecentBlogPosts which fetches a blog feed using
444+ # urlfetch.
445+ view.getRecentBlogPosts = lambda: []
446 content = BeautifulSoup(view(), parseOnlyThese=SoupStrainer('a'))
447 self.failUnless(
448 content.find('a', href='+featuredprojects'),
449
450=== modified file 'lib/lp/app/stories/launchpad-root/front-pages.txt'
451--- lib/lp/app/stories/launchpad-root/front-pages.txt 2010-05-19 05:47:50 +0000
452+++ lib/lp/app/stories/launchpad-root/front-pages.txt 2010-07-21 18:54:52 +0000
453@@ -1,59 +1,74 @@
454-= Launchpad front pages =
455+Launchpad front pages
456+---------------------
457
458 Visit our home page:
459
460- >>> browser.open('http://launchpad.dev/')
461- >>> browser.url
462- 'http://launchpad.dev/'
463+ >>> browser.open('http://launchpad.dev/')
464+ >>> browser.url
465+ 'http://launchpad.dev/'
466
467 It contains a string which our IS uses to determine whether or not
468 Launchpad is alive:
469
470- >>> print browser.contents
471- <!DOCTYPE...
472- ...
473- <!-- Is your project registered yet? -->
474- ...
475+ >>> print browser.contents
476+ <!DOCTYPE...
477+ ...
478+ <!-- Is your project registered yet? -->
479+ ...
480
481 And links to the important applications and facets:
482
483- >>> code_link = browser.getLink(url='code')
484- >>> code_link.url
485- 'http://code.launchpad.dev/'
486+ >>> code_link = browser.getLink(url='code')
487+ >>> code_link.url
488+ 'http://code.launchpad.dev/'
489
490 It also includes a search form...
491
492- >>> print browser.getControl('Search Launchpad').value
493- Search Launchpad
494+ >>> print browser.getControl('Search Launchpad').value
495+ Search Launchpad
496
497 ...and lists of featured projects and marketing material.
498
499- >>> featured = find_tag_by_id(browser.contents, 'homepage-featured')
500- >>> print extract_text(featured.renderContents())
501- Featured projects
502- ...
503- Ubuntu
504- ...
505+ >>> featured = find_tag_by_id(browser.contents, 'homepage-featured')
506+ >>> print extract_text(featured.renderContents())
507+ Featured projects
508+ ...
509+ Ubuntu
510+ ...
511
512 The footer doesn't contain the links that are already present on the page.
513
514 >>> print find_tags_by_class(browser.contents, 'lp-arcana')
515 []
516
517-The homepage looks different when the use is logged in:
518-
519- >>> user_browser = setupBrowser(auth="Basic test@canonical.com:test")
520- >>> user_browser.open('http://launchpad.dev/')
521+The front page also lists the recent blog posts published on the Launchpad
522+blog:
523+
524+ >>> print extract_text(
525+ ... find_tag_by_id(browser.contents, 'homepage-blogposts'))
526+ Recent Launchpad blog posts
527+ Launchpad EPIC 2010 photo
528+ &ndash; 16 Jul 2010
529+ The Launchpad and Bazaar teams have been in Prague this week...
530+ Three tips for faster launchpadlib api clients
531+ &ndash; 14 Jul 2010
532+ Three tips from Leonard...
533+ New Launchpad Bugs Status: Opinion...
534+
535+The homepage looks different when the user is logged in:
536+
537+ >>> user_browser = setupBrowser(auth="Basic test@canonical.com:test")
538+ >>> user_browser.open('http://launchpad.dev/')
539
540 Now there are links to create projects and teams:
541
542- >>> project_link = user_browser.getLink(url='/projects')
543- >>> project_link.url
544- 'http://launchpad.dev/projects/+new'
545+ >>> project_link = user_browser.getLink(url='/projects')
546+ >>> project_link.url
547+ 'http://launchpad.dev/projects/+new'
548
549- >>> people_link = user_browser.getLink(url='/people')
550- >>> people_link.url
551- 'http://launchpad.dev/people/+newteam'
552+ >>> people_link = user_browser.getLink(url='/people')
553+ >>> people_link.url
554+ 'http://launchpad.dev/people/+newteam'
555
556
557 The front pages for the other applications, however, do have
558
559=== modified file 'lib/lp/app/templates/root-index.pt'
560--- lib/lp/app/templates/root-index.pt 2010-06-25 16:31:46 +0000
561+++ lib/lp/app/templates/root-index.pt 2010-07-21 18:54:52 +0000
562@@ -128,34 +128,20 @@
563 </div>
564 </div>
565
566- <div id="homepage-blogposts" class="homepage-portlet">
567+ <div id="homepage-blogposts" class="homepage-portlet"
568+ tal:content="cache:public, 1 hour">
569 <h2>Recent Launchpad blog posts</h2>
570- <ul>
571- <li class="news">
572- <a href="http://www.surveymonkey.com/s/launchpadsummer2010">
573- Take the Launchpad survey</a><span class="registered"> &ndash; 01 July 2010</span><br />
574- Tell us a little about how you use Launchpad by answering our short survey.
575- </li>
576- <li class="news">
577- <a href="http://blog.launchpad.net?p=1607">
578- SFTP uploads</a><span class="registered"> &ndash; 01 July 2010</span><br />
579- Upload source packages to your Personal Package Archive using SFTP.
580- </li>
581- <li class="news">
582- <a href="http://blog.launchpad.net?p=1513">
583- 2GiB PPAs for everyone!</a><span class="registered"> &ndash; 04 May 2010</span><br />
584- We've doubled the standard Personal Package Archive size to 2 GiB.
585- </li>
586- <li class="news">
587- <a href="http://blog.launchpad.net?p=1491">
588- Automatic translation template generation</a><span class="registered"> &ndash; 04 May 2010</span><br />
589- Opening a project for translation is now easier with automatic template generation direct from the
590- project's Bazaar branch.
591- </li>
592- <li class="news">
593- <a href="http://blog.launchpad.net?p=1503">
594- Link projects to Ubuntu packages</a><span class="registered"> &ndash; 04 May 2010</span><br />
595- Launchpad now helps you specify which Ubuntu package is associated with any project in Launchpad.
596+ <ul tal:define="posts view/getRecentBlogPosts">
597+ <li class="news"
598+ tal:repeat="post posts">
599+ <a href="" tal:attributes="href post/link"
600+ tal:content="post/title">
601+ Take the Launchpad survey</a><span class="registered">
602+ &ndash; <tal:date content="post/date">01 July 2010</tal:date></span><br />
603+ <tal:description content="structure post/description">
604+ Tell us a little about how you use Launchpad by answering
605+ our short survey.
606+ </tal:description>
607 </li>
608 <li class="news">
609 <a href="http://blog.launchpad.net/general/launchpad-is-now-open-source">
610
611=== modified file 'setup.py'
612--- setup.py 2010-07-16 13:26:11 +0000
613+++ setup.py 2010-07-21 18:54:52 +0000
614@@ -31,6 +31,7 @@
615 'cssutils',
616 # Required for pydkim
617 'dnspython',
618+ 'FeedParser',
619 'feedvalidator',
620 'funkload',
621 'launchpadlib',
622
623=== modified file 'versions.cfg'
624--- versions.cfg 2010-07-16 13:26:11 +0000
625+++ versions.cfg 2010-07-21 18:54:52 +0000
626@@ -17,6 +17,7 @@
627 dnspython = 1.7.1
628 elementtree = 1.2.6-20050316
629 epydoc = 3.0.1
630+FeedParser = 4.1
631 feedvalidator = 0.0.0DEV-r1049
632 functest = 0.8.7
633 funkload = 1.10.0