App-jupiter
view release on metacpan or search on metacpan
# DESCRIPTION
Planet Jupiter is used to pull together the latest updates from a bunch of other
sites and display them on a single web page, the "river of news". The sites we
get our updates from are defined in an OPML file.
A river of news, according to Dave Winer, is a feed aggregator. New items appear
at the top and old items disappear at the bottom. When it's gone, it's gone.
There is no count of unread items. The goal is to fight the _fear of missing
out_ (FOMO).
Each item looks similar to every other: headline, link, an extract, maybe a date
and an author. Extracts contain but the beginning of the article's text; all
markup is removed; no images. The goal is to make the page easy to skim.
Scroll down until you find something interesting and follow the link to the
original article if you want to read it.
## The OPML file
You **need** an OPML file. It's an XML file linking to _feeds_. Here's an
example listing just one feed. In order to add more, add more `outline`
elements with the `xmlUrl` attribute. The exact order and nesting does not
matter. People can _import_ these OPML files into their own feed readers and
thus it may make sense to spend a bit more effort in making it presentable.
<opml version="2.0">
<body>
<outline title="Alex Schroeder"
xmlUrl="https://alexschroeder.ch/view/index.rss"/>
</body>
</opml>
## Update the feeds in your cache
This is how you update the feeds in a file called `feed.opml`. It downloads all
the feeds linked to in the OPML file and stores them in the cache directory.
jupiter update feed.opml
The directory used to keep a copy of all the feeds in the OPML file has the same
name as the OPML file but without the .opml extension. In other words, if your
OPML file is called `feed.opml` then the cache directory is called `feed`.
This operation takes long because it requests an update from all the sites
listed in your OPML file. Don't run it too often or you'll annoy the site
owners.
The OPML file must use the .opml extension. You can update the feeds for
multiple OPML files in one go.
## Adding just one feed
After a while, the list of feeds in your OPML starts getting unwieldy. When you
add a new feed, you might not want to fetch all of them. In this case, provide a
regular expression surrounded by slashes to the `update` command:
jupiter update feed.opml /example/
Assuming a feed with a URL or title that matches the regular expression is
listed in your OPML file, only that feed is going to get updated.
There is no need to escape slashes in the regular expression: `//rss/` works
just fine. Beware shell escaping, however. Most likely, you need to surround the
regular expression with single quotes if it contains spaces:
jupiter update feed.opml '/Halberds & Helmets/'
Notice how we assume that named entities such as `&` have already been
parsed into the appropriate strings.
## Generate the HTML
This is how you generate the `index.html` file based on the feeds of your
`feed.opml`. It assumes that you have already updated all the feeds (see
above).
jupiter html feed.opml
See ["OPTIONS"](#options) for ways to change how the HTML is generated.
## Generate the RSS feed
This happens at the same time as when you generate the HTML. It takes all the
entries that are being added to the HTML and puts the into a feed.
See ["OPTIONS"](#options) for ways to change how the HTML is generated.
## Why separate the two steps?
The first reason is that tinkering with the templates involves running the
program again and again, and you don't want to contact all the sites whenever
you update your templates.
The other reason is that it allows you to create subsets. For example, you can
fetch the feeds for three different OPML files:
jupiter update osr.opml indie.opml other.opml
And then you can create three different HTML files:
jupiter html osr.html osr.opml
jupiter html indie.html indie.opml
jupiter html rpg.html osr.opml indie.opml other.opml
For an example of how it might look, check out the setup for the planets I run.
[https://alexschroeder.ch/cgit/planet/about/](https://alexschroeder.ch/cgit/planet/about/)
## What about the JSON file?
There's a JSON file that gets generated and updated as you run Planet Jupiter.
It's name depends on the OPML files used. It records metadata for every feed in
the OPML file that isn't stored in the feeds themselves.
`message` is the HTTP status message, or a similar message such as "No entry
newer than 90 days." This is set when updating the feeds in your cache.
`message` is the HTTP status code; this code could be the real status code from
the server (such as 404 for a "not found" status) or one generated by Jupiter
such that it matches the status message (such as 206 for a "partial content"
status when there aren't any recent entries in the feed). This is set when
updating the feeds in your cache.
`title` is the site's title. When you update the feeds in your cache, it is
taken from the OPML file. That's how the feed can have a title even if the
download failed. When you generate the HTML, the feeds in the cache are parsed
and if a title is provided, it is stored in the JSON file and overrides the
title in the OPML file.
`link` is the site's link for humans. When you generate the HTML, the feeds in
the cache are parsed and if a link is provided, it is stored in the JSON file.
If the OPML element contained a `htmlURL` attribute, however, that takes
precedence. The reasoning is that when a podcast is hosted on a platform which
generates a link that you don't like and you know the link to the human-readable
blog elsewhere, use the `htmlURL` attribute in the OPML file to override this.
`last_modified` and `etag` are two headers used for caching from the HTTP
response that cannot be changed by data in the feed.
If we run into problems downloading a feed, this setup allows us to still link
to the feeds that aren't working, using their correct names, and describing the
error we encountered.
## Logging
Use the `--log=LEVEL` to set the log level. Valid values for LEVEL are debug,
info, warn, error, and fatal.
# LICENSE
GNU Affero General Public License
# INSTALLATION
Using `cpan`:
cpan App::jupiter
Manual install:
perl Makefile.PL
make
make install
## Dependencies
To run Jupiter on Debian we need:
`libmodern-perl-perl` for [Modern::Perl](https://metacpan.org/pod/Modern%3A%3APerl)
`libmojolicious-perl` for [Mojo::Template](https://metacpan.org/pod/Mojo%3A%3ATemplate), [Mojo::UserAgent](https://metacpan.org/pod/Mojo%3A%3AUserAgent), [Mojo::Log](https://metacpan.org/pod/Mojo%3A%3ALog),
( run in 0.479 second using v1.01-cache-2.11-cpan-f56aa216473 )