PluginProbe
FeedWordPress / 0.97
FeedWordPress v0.97
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
feedwordpress / README.text

README.text in FeedWordPress 0.97, at README.text

510 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 FeedWordPress
2 =============
3
4 * Author: [Charles Johnson](http://radgeek.com/contact)
5 * Version: 0.97
6 * Project URI: <http://projects.radgeek.com/feedwordpress>
7 * License: GPL 2. See License below for copyright jots and tittles.
8
9 Introduction
10 ------------
11 FeedWordPress is an Atom/RSS aggregator for WordPress 1.5. It syndicates content
12 from newsfeeds that you choose into your WordPress blog; if you syndicate
13 several newsfeeds then you can use WordPress's posts database and templating
14 engine as the back-end of an aggregation ("planet") website. I originally
15 developed it because I needed a more flexible replacement for [Planet][] to
16 use at [Feminist Blogs][].
17
18 [Planet]: http://www.planetplanet.org/ "Planet Planet"
19 [Feminist Blogs]: http://www.feministblogs.org/
20
21 FeedWordPress is designed with flexibility, ease of use, and ease of
22 configuration in mind. You'll need a working installation of [WordPress
23 1.5][] and FTP or SFTP access to your web host. The ability to create cron
24 jobs on your web host would be very helpful but it's not absolutely
25 necessary. You *don't* need to tweak any plain-text configuration files and
26 you *don't* need shell access to your web host to make it work. (Although, I
27 should point out, web hosts that *don't* offer shell access are *bad web
28 hosts*.)
29
30 [WordPress 1.5]: http://wordpress.org/development/2005/02/strayhorn/
31
32 Installation
33 ------------
34 ### Requirements ###
35
36 To use version 0.97 of FeedWordPress, you will need:
37
38 1. an installed configured copy of WordPress 1.5.x. (It *won't work* with
39 WP 1.2 or WP 1.6 development builds.)
40
41 2. FTP or SFTP access to your web host
42
43 And you'll probably also want to have either:
44
45 1. the ability to create cron jobs on your web host, or at least
46
47 2. a computer of your own and always-on Internet access
48
49 ### Installation ###
50
51 #### Upgrades ####
52
53 To *upgrade* an existing installation of FeedWordPress to version 0.97:
54
55 1. Download the FeedWordPress archive in zip or gzipped tar format and
56 extract the files on your computer. Replace your existing FeedWordPress
57 files with the new files. Be sure to upgrade `rss-functions.php` if you
58 use the optional MagpieRSS upgrade, or don't use it yet but do want to
59 syndicate Atom 1.0 feeds.
60
61 2. **Immediately** log in to the WordPress Dashboard, and go to Options -->
62 Syndicated. Follow the directions to launch the database upgrade
63 procedure. The new version of FeedWordPress incorporates some
64 long-needed improvements, but old meta-data needs to be updated to
65 prevent duplicate posts and other possible maladies. If you're upgrading
66 an existing installation, updates and FeedWordPress template functions
67 *will not work* until you've done the upgrade.
68
69 3. Take a coffee break while the upgrade runs. It should, hopefully, finish
70 within a few minutes even on relatively large databases.
71
72 4. `update-feeds.php` has been overhauled to improve performance and ease
73 of use, and also to make errors easier to detect and eliminate. The
74 overhaul doesn't require any changes to your set up *if* you used
75 XML-RPC pings, or command-line PHP, to do scheduled updates. It *does*
76 affect you if you used curl or some other tool to send HTTP requests to
77 `update-feeds.php`: your old cron job will probably not work anymore.
78 See [Setting Up Feed Updates][] below to get scheduled updates back on
79 track.
80
81 5. Enjoy your new installation of FeedWordPress.
82
83 #### New Installations ####
84
85 1. Install `feedwordpress.php` in your WordPress `plugins` directory
86 and `update-feeds.php` in your WordPress `wp-content` directory.
87
88 2. (Optional) Upgrade the copy of MagpieRSS packaged with WordPress by
89 installing the new `rss-functions.php` (archived in
90 `OPTIONAL/wp-includes`) into your WordPress `wp-includes` directory.
91 Upgrading MagpieRSS is necessary if you want to take advantage of
92 support for Atom 1.0, multiple post categories, RSS enclosures, and
93 multiple character encodings. (Note, however, that support for
94 transliterating between character encodings is a very complex and
95 iffy prospect in some PHP environments, so if you intend to use
96 a lot of feeds with alternate encodings you should make sure that
97 your installation of PHP is up-to-date and that you keep a copy of
98 the old MagpieRSS around to compare results.)
99
100 3. Log in to the WordPress Dashboard and activate the FeedWordPress
101 plugin.
102
103 4. While you're at the Dashboard, once the plugin is activated, you can
104 go to Options --> Syndication and set (1) the link category that
105 FeedWordPress will syndicate links from (by default, "Contributors"),
106 and (2) a "secret word" for your RPC-XML updating interface. This
107 provides some light security by keeping passing ruffians from saying
108 "Update all the feeds" at will to your FeedWordPress installation.
109
110 5. Go to Links --> Syndicated to set up the list of sites that you want
111 FeedWordPress to syndicate onto your blog. (If you have the feeds you
112 want to aggregate in a service such as Bloglines, you may prefer to
113 export them to an OPML file and use WordPress's Links --> Import to
114 import them into the contributors category.)
115
116 #### Setting Up Feed Updates ####
117
118 FeedWordPress is now ready to accept posts from its syndication sources.
119 Unfortunately, it doesn't yet know *when* to go get them. (**This may be true
120 even if you are upgrading an existing installation of FeedWordPress:** your old
121 cron job will still work if you used command-line PHP or blogging software pings
122 to do updates, but it will need to be fixed if you used curl or another tool to
123 send HTTP requests to `update-feeds.php`.)
124
125 You can load in syndicated posts for the first time by pointing your web browser
126 to `update-feeds.php`. If you have WordPress installed at, say,
127 <http://www.zyx.com/blog> then you should point your browser to
128 <http://www.zyx.com/blog/wp-content/update-feeds.php> and log in as any user in
129 the user database. (You may want to create a new "dummy" user for doing
130 scheduled updates, using **Users --> Authors & Users --> Add New User**. Tell
131 FeedWordPress to update all feeds, and you'll get the first wave of posts
132 imported into the database.
133
134 Congratulations! You should now have an aggregator site full of delicious
135 syndicated content hot off of the newswires. Now you just need a way to *keep*
136 the content freshly updated. Unless you enjoy manually browsing to
137 `update-feeds.php` every hour on the hour, you'll probably want to do this by
138 setting up your site for automated updates.
139
140 You can pull that off in one of two ways, or by a mixture of both:
141
142 1. **The Blogging Software Ping Method:** You can get all of your
143 contributors to add you to the list of URIs that they notify of updates:
144 while FeedWordPress is activated, it will accept XML-RPC "recently
145 updated" pings in the standard format accepted by Weblogs.com,
146 Ping-O-Matic, Technorati, and other services. Most blogging software
147 allows users to add a URI to the list of URIs that get pinged on each
148 update. (See, for example, Options --> Writing --> Update Services in
149 WordPress, or Configuration --> Preferences --> Publicity / Remote
150 Interfaces / TrackBack in Movable Type.)
151
152 If you can get a contributor to add your XML-RPC URI to her
153 services-to-ping list (if you have WordPress installed at
154 <http://www.zyx.com/blog>, say, the URI to add should be
155 <http://www.zyx.com/blog/xmlrpc.php>), then whenever she updates her
156 blog, her blogging software will ping your FeedWordPress installation,
157 and FeedWordPress will look up her feed to grab the new posts off of
158 it.
159
160 2. **The Scheduled Update Job Method:** You may very well not be able to
161 get all your contributors to add your site to their blogging software's
162 ping list, and even if you do you may want to have a back-up option to
163 catch updates later even if the ping fails to go through on one
164 particular occasion. You'll need to create a scheduled job to
165 periodically check for updates on *all* the feeds. You'll need either
166 (a) the ability to create cron jobs on your web host or (b) access to
167 another computer with a reliable, always-on Internet connection.
168
169 If you *can* create a crontab on your web host, then the best thing to
170 do is to create a cron job that will run update-feeds.php through the
171 PHP command-line interface. For example, if you have WordPress installed
172 in `~/www/wp` (where ~ is your home directory), you might insert the
173 following line into your crontab:
174
175 25 * * * * cd $HOME/www/wp/wp-content ; php -q update-feeds.php
176
177 If you *don't* have access to (a), you can still save the day using
178 another computer with always-on Internet access that sends a POST
179 request to the `update-feeds.php` URI on a regular schedule. So, for
180 example, if you have WordPress installed at <http://www.zyx.com/blog>,
181 and you have a dummy user in your WordPress database with the login name
182 'login' and the password 'pass', then you could add the following line
183 to the crontab on a home Linux box:
184
185 25 * * * * curl --user login:pass http://www.zyx.com/blog/wp-content/update-feeds.php -d update=quiet
186
187 The `-d update=quiet` switch ensures that (1) `update-feeds.php` will
188 receive an HTTP POST request rather than an HTTP GET request (which
189 is important, since it won't take any actions with side-effects -- such
190 as checking for new posts -- unless it receives an HTTP POST); it also
191 tells it to suppress the HTML output that it would generate for normal
192 web browsers, and only to output text if it encounters errors (this will
193 keep the number of e-mails you receive from the Cron Daemon to a
194 minimum).
195
196 If you are using Windows XP and have a version of curl (such as the
197 version included in [Cygwin][]), you can create a Scheduled Task to
198 similar effect.
199
200 [Cygwin]: http://www.cygwin.com/
201
202 Basic Concepts
203 --------------
204 FeedWordPress is written as a plugin for [WordPress 1.5][]. It is designed to
205 store all the data it needs within the WordPress database and to make that data
206 easy to manage from within the WordPress Dashboard.
207
208 ### Contributors / Newsfeeds ###
209
210 FeedWordPress uses the WordPress Links database to keep a list of the feeds from
211 which it will syndicate content. WordPress allows you to place links in
212 categories; FeedWordPress will make use of all and only the links in one
213 category (by default, this is a category named "Contributors"; you can change
214 the category that FeedWordPress will use using **Options --> Syndication**).
215
216 From WordPress's perspective, the list of Contributors are normal links, and
217 they can be manipulated like other links through the WordPress Dashboard.
218 However, FeedWordPress provides a nicer interface for adding, removing, or
219 changing information for the Contributor Links from the WordPress Dashboard,
220 under **Links --> Syndicated**.
221
222 If you want to distribute the labor of adding, updating, and managing feeds
223 between several people, you can use the WordPress login andaccess privileges
224 system. Any users with an access level of 5 or greater can add, delete, and
225 modify Contributors; users with an access level of 6 or greater can change
226 syndication options.
227
228 When FeedWordPress looks for new posts, it retrieves one or all of the links
229 from the Contributors category (depending on whether it has been told to scan
230 for new posts on one or all of the feeds), determines which of them should be
231 polled for updates (based on how long it has been since the last time each feed
232 was polled for updates), and then uses an HTTP conditional GET to check for
233 updates at the "RSS URI" for each Link that it selects. Any new posts are added
234 to the database, and old posts that have been updated since the last poll are
235 updated to reflect the new version.
236
237 __Feed settings:__ All of the information for a syndicated feed is stored in the
238 WordPress Links database, and can be easily edited using an interface that
239 FeedWordPress provides under **Links --> Syndicated**. (If you're curious about
240 the technical details of how the information is stored, you can find out more
241 under [API: How feed information is stored][].)
242
243 You can use a feed's **Edit** link under **Links --> Syndicated** to affect how
244 FeedWordPress prcesses posts from that feed. (Most of these options can either
245 be set for *one particular feed* using **Links --> Syndicated --> Edit**, or set
246 as the default for *all feeds* using **Options --> Syndication**.) The **Edit**
247 link also allows you to set **Custom Feed Settings** for use in templates,
248 through the use of the [`get_feed_meta()`][get_feed_meta] template function in a
249 post context (see [Template API][]). For example, many aggregator sites use a
250 "face" image for each feed to visually distinguish posts from different feeds.
251 To implement a face feature, you could add a custom setting for each Contributor
252 Link, with the key of "face" and a URI such as "http://www.zyx.com/mugs/ugly"
253 for the value. (The URI should be changed out for each feed to point to the
254 appropriate image, of course.) Then, to use the setting from within a template,
255 add something like:
256
257 // In a post context
258 <?php $img = get_feed_meta('face'); if (strlen($img) > 0): ?>
259 <img src="<?=$img?>" alt="" />
260 <?php endif; ?>
261
262 ... which will display the image, if any, whose URI is set in the "face" setting
263 for the feed that post comes from. If there is no "face" setting for a
264 particular feed, [`get_feed_meta()`][get_feed_meta] will return an empty string
265 and no image will be displayed.
266
267 [API: How feed information is stored]: http://projects.radgeek.com/feedwordpress/api#how-feed-information-is-stored
268
269 ### Syndicated Posts ###
270
271 Whenever FeedWordPress updates, it scans one or more of the feeds in its
272 Contributors list and adds any new posts that it finds to the WordPress
273 database. Syndicated posts are displayed on your WordPress pages like any other
274 posts: they can be listed in archives by category, author, or date; they can be
275 found with the search box; and they are included in the newsfeed of your blog.
276
277 In your WordPress templates (**Presentation --> Theme Editor**) you can access
278 special information about syndicated posts using [functions provided by
279 FeedWordPress][Template API], such as [`is_syndicated()`][is_syndicated],
280 [`the_syndication_source()`][the_syndication_source],
281 [`the_syndication_source_link()`][the_syndication_source_link], and
282 [`get_feed_meta()`][get_feed_meta]. For example, here is the template code that
283 I use (in a post context) to display both the author's name and the original
284 source of the post in the templates for [Feminist Blogs][]:
285
286 <cite class="feed">from <?php the_author_posts_link()?><?php
287 if (is_syndicated() and (get_the_author() !== get_syndication_source())):
288 echo ' @ <a href="'; the_syndication_source_link(); echo '">';
289 the_syndication_source();
290 echo '</a>';
291 endif; ?></cite>
292
293 For more information on template functions, see [Template API][].
294
295 ### Categories ###
296
297 WordPress allows for posts to be placed in *categories*. Each syndicated post
298 that FeedWordPress adds to the WordPress database is placed into a set of
299 categories. FeedWordPress gets the list of category names to use from two
300 sources:
301
302 1. Categories (or "tags") that the original author placed the post in on
303 her blog
304
305 2. Categories that you set explicitly for each feed using the
306 **Categories** checkbox under **Links --> Syndicated --> Edit**. For
307 example, if you wanted all the posts from Alas, A Blog to be placed in
308 the "Pacific Northwest" category and the "Cartoonists" category (*in
309 addition to* any other categories that they were placed in on Alas, A
310 Blog), you could do this by creating the categories, going to **Links
311 --> Syndicated**, clicking the "Edit" link for Alas, A Blog, and
312 checking those two categories under the checkbox captioned "Categories."
313
314 Given the list of category names, FeedWordPress looks for categories in the
315 WordPress database with the same name as either (1) the category name, or
316 (2) one of the "aliases" listed in the category description.
317
318 __Aliases:__ Different often authors use slightly different names for categories
319 that mean the same thing (contributors to Feminist Blogs, for example, used
320 categories including "Feminism", "feministy stuff", "Women's Issues", "Gender
321 Issues", "Gender Equality", and so on). If you want FeedWordPress to treat one
322 category name as a synonym for another, you can do so by creating an "alias" for
323 the category. For example, to make FeedWordPress treat posts that are placed in
324 the category "feministy stuff" as if they had been placed in the category
325 "Feminism", go to **Manage --> Categories**, find the category "Feminism" and
326 click the "Edit" link for it, and then add the following to the Description
327 field, on a line by itself:
328
329 a.k.a.: feministy stuff
330
331 You can add as many aliases as you like. You can also add any other text that
332 you like to the Description without interfering with FeedWordPress's ability to
333 use the aliases. Each alias must be on a line by itself.
334
335 __Unfamiliar categories:__ If one of the category names that a newsfeed provides
336 is *unfamiliar* -- that is, if there is not yet any category in your WordPress
337 database that either has that name, or uses that name as an alias -- then by
338 default FeedWordPress will *automatically create* a new category with that name
339 and place the current post in it. The default behavior can be changed so that
340 unfamiliar categories will *not* be added to the database, using the
341 **Unfamiliar categories** setting, either for *all* feeds (under **Options -->
342 Syndication**) or for *one particular feed* (under **Links --> Syndicated**).
343
344 If you choose to disable the creation of new categories, either for all feeds or
345 for one particular feed, then you can also choose whether or not FeedWordPress
346 should syndicate posts that do not match *any* of the categories that are
347 currently in the database. This allows you to do some simple filtering of posts
348 by category: if you want to your blog to syndicate only the posts in one
349 particular category from a feed that has several categories, you could do so by
350 creating a category by that name, adding the new feed(s), and then setting
351 **Unfamiliar categories** under **Links --> Syndicated --> Edit** to "don't
352 create new categories and don't syndicate posts unless they match at least one
353 familiar category".
354
355 Since only posts in categories that are in your database will be included, and
356 only the category or categories that you wanted posts from has been added to
357 your database, this will filter out all the posts that aren't in the category or
358 categories that you defined ahead of time. (Similarly, you could set up
359 FeedWordPress so that *all* the feeds are filtered by author by creating the set
360 of users named after the authors you want to syndicate, and then setting the
361 default behavior for *all* feeds at **Options --> Syndication**).
362
363 If you need a category filter with more complex logic, you can always create a
364 `syndicated_item` filter in PHP (see [Plugin API][]) that manipulates the
365 `['categories']` array of a syndicated item.
366
367 ### Authors ###
368
369 Most newsfeeds include information about the author of the items on them.
370 (If a feed doesn't, then FeedWordPress will create an author's name based on
371 the title of the feed from which the item was taken.) This information is used
372 to determine the WordPress user that the post will be attributed to. Given the
373 name of the author, FeedWordPress looks for authors in the WordPress database
374 with the same name as either (1) their login, (2) their first name, (3) their
375 nickname, (4) their full name, or (5) one of the "aliases" listed in the
376 user's profile.
377
378 __Aliases:__ If there is an author who posts under more than one name (for
379 example, one of our contributors at [Feminist Blogs][] posts on several
380 different blogs, sometimes using her full name and sometimes using only her
381 first name), then you can ensure that FeedWordPress will attribute those posts
382 to the same author by creating "aliases" for the author. For example, to make
383 FeedWordPress treat posts by "Joseph Cardinal Ratzinger" and posts by "Pope
384 Benedict XVI" as having the same author, go to **Users --> Authors & Users**,
385 click on the "Edit" link for Pope Benedict XVI, and add a line like this to the
386 Profile text:
387
388 a.k.a.: Joseph Cardinal Ratzinger
389
390 You can add as many aliases as you like. You can also add any other text that
391 you like to the Profile without interfering with FeedWordPress's ability to use
392 the aliases. Each alias must be on a line by itself.
393
394 __Unfamiliar authors:__ By default, if the author named by the newsfeed is
395 unfamiliar -- that is, if there is no-one with that name registered in the
396 WordPress author's database -- then by default FeedWordPress will automatically
397 create a new user account with the given name and attribute the post to the new
398 user. The default behavior can be changed, using either the global settings in
399 **Options --> Syndication** or the [feed settings][] under **Links -->
400 Syndicated --> Edit**, so that posts by unfamiliar authors will either be
401 attributed to a default author (instead of creating a new user account to
402 attribute them to), or filtered out and not syndicated at all.
403
404 One of the uses of this feature is to filtering posts by author: if you want to
405 your blog to syndicate only the posts by one particular author from a feed that
406 has several authors, you could do so by creating a user account with that
407 author's name, adding the new feed(s), and then setting **Unfamiliar authors**
408 under **Links --> Syndicated --> Edit** to "don't syndicate the post". Since
409 only posts by authors that are in your database will be included, and only the
410 author that you wanted posts from has been added to your database, this will
411 filter out posts by anyone else on the feeds with that setting. (Similarly, you
412 could set up FeedWordPress so that *all* the feeds are filtered by author by
413 creating the set of users named after the authors you want to syndicate, and
414 then setting the default behavior for *all* feeds at **Options -->
415 Syndication**).
416
417 If you need an author filter with more complex logic than this allows, you can
418 always create a `syndicated_item` filter in PHP (see [Plugin API][]) that
419 manipulates the `['author_name']` or `['dc']['creator']` elements of a
420 syndicated item.
421
422 Template API
423 ------------
424 When activated, FeedWordPress makes the following functions available for use by
425 themes/templates:
426
427 * ``is_syndicated()``: in a post context, returns ``TRUE`` if the post was
428 syndicated from another website, or ``FALSE`` if it was originally
429 posted here
430
431 * ``get_syndication_permalink()``: in a post context, returns the URI of
432 the permalink for this post *on the website it was syndicated from*
433
434 * ``the_syndication_permalink()``: in a post context, outputs the value
435 returned by [``get_syndication_permalink()``][get_syndication_permalink]
436
437 * ``get_syndication_source_link()``: in a post context, returns the URI of
438 the front page (*not* the feed) of the website this post was syndicated
439 from
440
441 * ``the_syndication_source_link()``: in a post context, outputs the URI
442 returned by
443 [``get_syndication_source_link()``][get_syndication_source_link]
444
445 * ``get_syndication_source()``: in a post context, returns the
446 human-readable title of the website that a syndicated post was
447 syndicated from
448
449 * ``the_syndication_source()``: in a post context, outputs the value
450 returned by [``get_syndication_source()``][get_syndication_source]
451
452 * ``get_syndication_feed():`` in a post context, returns the URI of the
453 feed (*not* the front page) that this post was syndicated from
454
455 * ``the_syndication_feed()``: in a post context, outputs the value
456 returned by [``get_syndication_feed()``][get_syndication_feed]
457
458 * ``get_feed_meta($key)``: in a post context, returns the value, if any,
459 of the feed setting ``$key`` for the feed that this post was syndicated
460 from
461
462 By default, FeedWordPress also places a filter on the standard functions
463 ``get_permalink()`` and ``the_permalink()`` that substitutes the URI returned by
464 [``get_syndication_permalink()``][get_syndication_permalink] for the URI
465 generated by WordPress. This means that by default the permalinks listed on your
466 website and in your newsfeed will link to the location of the posts on the
467 source website, *not* to their location on your website. You can switch this
468 behavior on or off at **Options --> Syndication** in the WordPress Dashboard.
469
470 Plugin API
471 ----------
472 FeedWordPress creates five hooks through the WordPress plugin architecture that
473 you can plug in to using PHP WordPress plugins, to supplement ordinary
474 FeedWordPress behavior, or to filter posts according to criteria that you set.
475 The hooks are the action ``feedwordpress_update``, the action
476 ``feedwordpress_check_feed``, the action ``feedwordpress_update_complete``, the
477 filter ``syndicated_item``, the filter ``syndicated_post``, the action
478 ``post_syndicated_item``, and the action ``update_syndicated_item``.
479
480 For more information, see <http://projects.radgeek.com/feedwordpress/api>.
481
482 License
483 -------
484 The FeedWordPress plugin is copyright (c) 2005 by Charles Johnson. It uses code
485 derived or translated from:
486
487 - [wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
488 - [MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
489 - [HTTP Navigator 2][] by [Keyvan Minoukadeh](keyvan@k1m.com)
490 - [Ultra-Liberal Feed Finder][] by [Mark Pilgrim](mark@diveintomark.org)
491
492 according to the terms of the [GNU General Public License][].
493
494 This program is free software; you can redistribute it and/or modify it under
495 the terms of the [GNU General Public License][] as published by the Free
496 Software Foundation; either version 2 of the License, or (at your option) any
497 later version.
498
499 This program is distributed in the hope that it will be useful, but WITHOUT ANY
500 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
501 PARTICULAR PURPOSE. See the GNU General Public License for more details.
502
503 [wp-rss-aggregate.php]: http://laughingmeme.org/archives/002203.html
504 [MagpieRSS]: http://magpierss.sourceforge.net/
505 [HTTP Navigator 2]: http://www.keyvan.net/2004/11/16/http-navigator/
506 [Ultra-Liberal Feed Finder]: http://diveintomark.org/projects/feed_finder/
507
508 [GNU General Public License]: http://www.gnu.org/copyleft/gpl.html
509
510