Verified Commit e618a21a authored by Carl Schwan's avatar Carl Schwan 🚴
Browse files

Convert to Planet Jekyll

Drop rawdog for generating the planet and use Jekyll-planet instead. This is using the pluto engine under the hood.

Advantage is that we can reuse the jekyll theme used in multiples other websites and it is easier to create a custom theme for KDE.

Test Plan: Follow instructions in readme

Differential Revision:
parent 2d19a5a8
revision: c2ad1f31702d3865d9ab55a46f005e7b8ef2e742
jekyll-kde-theme (0.4.0)
jekyll (~> 3.8)
activemodel (
activesupport (=
activerecord (
activemodel (=
activesupport (=
activerecord-utils (0.4.1)
activesupport (
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2)
activityutils (0.1.2)
logutils (>= 0.6.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
colorator (1.1.0)
concurrent-ruby (1.1.6)
date-formatter (0.1.1)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
eventmachine (1.2.7)
faraday (1.0.0)
multipart-post (>= 1.2, < 3)
feedfilter (1.1.1)
textutils (>= 1.0.1)
feedparser (2.1.2)
logutils (>= 0.6.1)
textutils (>= 1.0.0)
fetcher (0.4.5)
logutils (>= 0.6)
ffi (1.12.2)
forwardable-extended (2.6.0)
gli (2.19.0)
http_parser.rb (0.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
iniparser (1.0.1)
jekyll (3.8.6)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 0.7)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (~> 1.14)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
jekyll-paginate (1.1.0)
jekyll-paginate-v2 (3.0.0)
jekyll (>= 3.0, < 5.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (1.17.0)
liquid (4.0.3)
listen (3.2.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logutils (0.6.1)
logutils-activerecord (0.2.1)
logutils (>= 0.6.1)
mercenary (0.3.6)
mini_portile2 (2.4.0)
minitest (5.14.0)
multipart-post (2.1.1)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
pakman (1.1.0)
fetcher (>= 0.4.5)
liquid (>= 4.0.0)
logutils (>= 0.6.1)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
pluto (1.3.4)
gli (>= 2.12.2)
pluto-merge (>= 1.1.0)
pluto-models (>= 1.5.4)
pluto-tasks (>= 1.5.3)
pluto-update (>= 1.6.3)
pluto-feedfetcher (0.1.4)
fetcher (>= 0.4.5)
pluto-models (>= 1.5.4)
pluto-merge (1.1.0)
fetcher (>= 0.4.4)
pakman (>= 0.5.0)
pluto-models (>= 1.2.2)
pluto-models (1.6.1)
activerecord-utils (>= 0.4.0)
activityutils (>= 0.1.1)
date-formatter (>= 0.1.1)
feedfilter (>= 1.1.1)
feedparser (>= 2.1.2)
logutils (>= 0.6.1)
logutils-activerecord (>= 0.2.1)
props (>= 1.2.0)
props-activerecord (>= 0.2.0)
textutils (>= 1.4.0)
pluto-tasks (1.5.3)
pluto-models (>= 1.4.0)
pluto-update (>= 1.6.0)
pluto-update (1.6.3)
pluto-feedfetcher (>= 0.1.4)
pluto-models (>= 1.5.4)
props (1.2.0)
iniparser (>= 0.1.0)
props-activerecord (0.2.0)
props (>= 1.2.0)
public_suffix (4.0.3)
rake (13.0.1)
rb-fsevent (0.10.3)
rb-inotify (0.10.1)
ffi (~> 1.0)
rouge (3.16.0)
rubyzip (2.2.0)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sqlite3 (1.4.2)
textutils (1.4.0)
logutils (>= 0.6.1)
props (>= 1.1.2)
rubyzip (>= 1.0.0)
thread_safe (0.3.6)
tzinfo (1.2.6)
thread_safe (~> 0.1)
zeitwerk (2.3.0)
Planet KDE uses rawdog
To add your blog edit planetkde/config and add your photo head to website/hackergotchi/myname.png
To run locally edit planetkde/config and set outputfile and outputxml to the right directory.
Run it with
./rawdog -d planetkde --update
./rawdog -d planetkde --write
will write to website/index.html and website/rss20.xml
Jonathan Riddell, 10-2008
rawdog: RSS Aggregator Without Delusions Of Grandeur
Adam Sampson <>
rawdog is an RSS (and other) feed aggregator, based on Mark Pilgrim's flexible
feed parser. It's just an aggregator; it's not a weblog authoring tool, nor is
it an NNTP gateway, outliner, mailserver or anything else. rawdog probably
only runs on Unix-like systems.
(Important: If you're upgrading from rawdog 1.x to rawdog 2.x, please
read the NEWS file to find out how to convert your rawdog state file.)
rawdog requires Python 2.2 or later. rawdog itself doesn't need any
additional modules to be installed, but it uses distutils for
installation, so if you're on a Debian system you'll need to install the
"python-dev" package first.
rawdog reads articles from a number of feeds and writes out a single
HTML file, based on a template either provided by the user or generated
by rawdog, containing the latest articles it's seen. It uses the ETags
and Last-Modified headers to avoid fetching a file that hasn't changed,
and supports gzip compression to reduce bandwidth when it has. It is
configured from a simple text file; the only state kept between
invocations that can't be reconstructed from the feeds is the ordering
of articles.
To install rawdog on your system, use distutils -- "python install".
This will install the library modules that rawdog needs, and will install the
"rawdog" binary that you can use to run it. (If you want to install to a
non-standard prefix, read the help provided by "python install
rawdog needs a config file to function. Make the directory ".rawdog" in your
$HOME directory, copy the provided file "config" into that directory, and edit
it to suit your preferences. (Comments in that file describe what each of the
options does.) You should copy the provided file "style.css" into the same
directory that you've told rawdog to write its HTML output to. (rawdog should
be usable from a browser that doesn't support CSS, but it won't be very
When you invoke rawdog from the command line, you give it a series of actions
to perform -- for instance, "rawdog --update --write" tells it to do the
"--update" action, then the "--write" action. The actions supported are
as follows:
"--update" (or "-u"): Fetch data from the feeds and store it. This could
take some time if you've got lots of feeds.
"--write" (or "-w"): Write out the HTML output file.
"--list" (or "-l"): List brief information about each of the feeds that
was known about when "--update" was last done.
"--update-feed SOMEURL" (or "-f SOMEURL"), where SOMEURL is the URL of a
known feed: Update that feed immediately, even if its period hasn't
elapsed since it was last updated. This is useful if you're trying to
debug your own feed.
"--config FILE" (or "-c FILE"), where FILE is an absolute path or a path
relative to your .rawdog directory: Read FILE as an additional config
file; any options provided in FILE will override those already set in
the main config file (with the exception of "feed", which is
cumulative). Note that $HOME/.rawdog/config will still be read first
even if you specify this option. This is useful if you want rawdog to
write two different output files with different sets of options ("rawdog
-u -w -c config2 -w" will first update and write with the main config
file, then read config2, then write again).
"--show-template" (or "-t"): Print the template currently in use to
stdout. This is useful as a starting point if you want to modify your
own template: do "rawdog -t >~/.rawdog/mytemplate" with "template
default" in your config file, and you'll get a copy of the default
template to edit.
"--show-itemtemplate" (or "-T"): As for "--show-template", but for the
item template.
"--add URL" (or "-a URL"): Add a new feed to the config file. This uses
Mark Pilgrim's "feedfinder" module to try to figure out a feed for any
given URL, so you can usually just give it the URL of a blog's main
page, and it'll automatically detect the appropriate feed. (It'll tell
you if it can't guess a feed for the URL you give it.)
There are also the following options which may only be supplied once
(they're read before any of the actions are performed):
"--help": Provide a brief summary of all the options rawdog supports,
and exit.
"--dir DIR" (or "-d DIR"), where DIR is a directory: Use DIR instead of
the $HOME/.rawdog directory. This is useful if you want to have two or
more completely different rawdog setups with different sets of feeds;
just create a directory for each.
"--verbose" (or "-v"): Print more information about what rawdog's doing
while it's working. This is useful for tracking down problems.
"--no-locking" (or "-N"): Don't attempt to lock the state file. rawdog
usually claims a lock on the state file so that you can't have more than
one instance of rawdog running at the same time. Unfortunately, some
operating systems and filesystems don't support file locking; you can
use this option to disable locking if you're in that situation.
"--no-lock-wait" (or "-W"): If the state file lock can't be claimed
immediately, exit silently. Normally, rawdog will wait until it can
claim the lock, then run as usual; however, if you've got a very large
number of feeds and a slow machine or network connection, and you run
rawdog periodically from cron, then you may find you often have a number
of rawdog processes competing for the lock. In that situation, use this
option so that you've really only ever got one rawdog process running at
"--upgrade OLDDIR NEWDIR": This option can be used to convert your state
file when upgrading from rawdog 1.x to rawdog 2.x; see the NEWS file for
more information. If you're not doing this, then it won't be of any use
to you.
You will want to run "rawdog -uw" periodically to fetch data and write
the output file. The easiest way to do this is to add a crontab entry
that looks something like this:
0,10,20,30,40,50 * * * * /path/to/rawdog -uw
(If you don't know how to use cron, then "man crontab" is probably a good
start.) This will run rawdog every ten minutes.
If you want rawdog to fetch URLs through a proxy server, then set your
"http_proxy" environment variable appropriately; depending on your version of
cron, putting something like:
at the top of your crontab should be appropriate. (The http_proxy variable will
work for many other programs too.)
In the event that rawdog gets horribly confused (for instance, if your system
clock has a huge jump and it thinks it won't need to fetch anything for the
next thirty years), you can forcibly clear its state by removing the
~/.rawdog/state file (and the ~/.rawdog/feeds/*.state files, if you've
got the "splitstate" option turned on).
If you don't like the appearance of rawdog, then customise the style.css file.
If you come up with one that looks much better than the existing one, please
send it to me!
This should, hopefully, be all you need to know. If rawdog breaks in
interesting ways, please tell me at the email address at the top of this file.
# 🌎 [Planet KDE](
Planet KDE is a web feed aggregator that collects blog posts from people who contribute to KDE.
If you are a KDE contributor you can have your blog on Planet KDE. Blog content should be mostly
KDE themed and not liable to offend. If you have a general blog you may want to set up a tag and
subscribe the feed for that tag only to Planet KDE.
## Adding your feed
If you want to get your feed added, we prefer Merge Requests via [](
* Fork this repository
* Edit [planet.ini]( and add:
[id] # replace id with your feed's unique identifier (a-z0-9-_) (eg. kde-dot)
title = # title of your feed (eg. KDE Dot)
feed = # url to your rss/atom feed (eg.
link = # link to the main page of your website (eg.
location = # two letter language code (eg. en)
avatar = # (optional) filename or url of your avatar (eg. kde.png)
author = # (optional) includes various space separated tags about the author:
# irc:freenode_nickname (eg. irc:myircnickname)
# gsoc
* Upload your avatar to [hackergotchi directory](
* Send a Pull Request
If you do not have a Git account, <a href="">file
a bug in Bugzilla</a> listing your name, Git account (if you have one), IRC nick (if you have one), RSS or
Atom feed and what you do in KDE. Attach a photo of your face for hackergotchi.
## Planet KDE Guidelines
Planet KDE is one of the public faces of the KDE project and is read by millions of users and potential
contributors. The content aggregated at Planet KDE is the opinions of its authors, but the sum of that
content gives an impression of the project. Please keep in mind the following guidelines for your blog
content and read the [KDE Code of Conduct]( The KDE project
reserves the right to remove an inappropriate blog from the Planet. If that happens multiple times, the
Community Working Group can be asked to consider what needs to happen to get your blog aggregated again.
If you are unsure or have queries about what is appropriate contact the KDE Community Working Group.
### Blogs should be KDE themed
The majority of content in your blog should be about KDE and your work on KDE. Blog posts about personal
subjects are also encouraged since Planet KDE is a chance to learn more about the developers behind KDE.
However blog feeds should not be entirely personal, if in doubt set up a tag for Planet KDE and subscribe
the feed from that tag so you can control what gets posted.
### Posts should be constructive
Posts can be positive and promote KDE, they can be constructive and lay out issues which need to be
addressed, but blog feeds should not contain useless, destructive and negative material. Constructive
criticism is welcome and the occasional rant is understandable, but a feed where every post is critical
and negative is unsuitable. This helps to keep KDE overall a happy project.
### You must be a KDE contributor
Only have your blog on Planet KDE if you actively contribute to KDE, for example through code, user
support, documentation etc.
### It must be a personal blog, or in a blog class
Planet KDE is a collection of blogs from KDE contributors.
### Do not inflame
KDE covers a wide variety of people and cultures. Profanities, prejudice, lewd comments and content
likely to offend are to be avoided. Do not make personal attacks or attacks against other projects on
your blog.
For further guidance on good practice see the <a href="">KDE Code of Conduct</a>.
## Development environment
To run this website locally, use the following commands:
bundler install
bundler exec rake build
bundler exec jekyll serve
and visit [](
task default: %w[build]
task :build do
system 'pluto update planet.ini'
ruby 'bin/jekyll-planet.rb'
sh "for post in _posts/*; do sed -i '/title:/s/\\\\o/\\\\\\o/g' \"$post\"; done"
task :test do
ruby 'tests/feedcheck.rb'
title: Planet KDE
description: >-
Planet KDE site providing newest news from the KDE Project
baseurl: ""
url: ""
sourcecode: ""
markdown: kramdown
- jekyll-paginate-v2
enabled: true
enabled: false
enabled: false
- 'language.html'
title: ':tag'
permalink: '/:tag'
path: "" # an empty string here means all files in the project
layout: "post"
theme: jekyll-kde-theme
style: compressed
enabled: true
per_page: 10
permalink: '/:num/'
sort_reverse: true
sort_field: 'created_at'
before: 2
after: 2
exclude: [, Gemfile, Gemfile.lock, planet.ini, planet.db, LICENSE, vendor, tests, bin, Rakefile]
navigation: {}
not_made_by_kde: true
use-kde-logo: true
name: English
img: en.svg
name: Polish
img: pl.svg
name: French
img: fr.svg
name: Spanish
img: es.svg
name: German
img: de.svg
name: Czech
img: cs.svg
name: Greek
img: gr.svg
name: Indonesian
img: id.svg
name: Japanese
img: ja.svg
name: Taiwanese
img: tw.svg
name: Portugese
img: pt.svg
name: Russian
img: ru.svg
{% if post.previous == false or != %}
<div class="row mx-2 mb-3">
<div class="col p-0">
<h3 class="mb-0">{{ | date: "%A" }}</h1>
<h4 class="mb-0">{{ | date: "%-d %B, %Y" }}</h3>
{% endif %}
<link rel="stylesheet" type="text/css" href="">
<div class="bg-light py-3 mb-3 border-bottom">
<div class="container">
<div class="d-flex">
<a href="{{ site.baseurl }}/global/atom.xml" class="btn btn-sm btn-warning ml-auto">
<i class="icon icon_rss"></i>
<div class="row col-md-10 mx-auto">
<div class="col-auto">
<img src="{{ site.baseurl }}/assets/img/planetkde.svg" alt="Planet KDE logo" style="min-width: 200px" />
<div class="col my-auto">
<h2>Welcome to Planet KDE</h2>
<h5>This is a feed aggregator that collects what the contributors to the <a href="">KDE Project</a> are writing on their respective blogs</h5>
<div class="col-12 text-center mt-3">
{% assign sorted = site.tags | sort %}
{% for tag in sorted %}
{% assign lang =[tag.first] %}
<a class="mx-2" title="{{ }}" href="{{ site.baseurl }}/{{ tag.first }}/">{{ }}</a>
{% endfor %}
<a class="mx-2" title="Mastodon" href="">Mastodon</a>
<a class="mx-2" title="Reddit" href="">r/kde</a>
<div class="container">
<div class="alert alert-info">To have your blog added to this aggregator, please read <a href="">the instructions</a>
{% if paginator.total_pages > 1 %}
<div class="col-12 p-3 d-flex">
<ul class="pagination mx-auto my-0">
{% if paginator.previous_page %}
<li class="page-item">
<a class="page-link" href="{{ paginator.previous_page_path | relative_url }}">
{% endif %}
{% assign highest_number = paginator.total_pages | minus: 3 %}
{% if < 4 %}
{% assign low_number = 1 %}
{% elsif > highest_number %}
{% assign low_number = paginator.total_pages | minus: 4 %}
{% else %}
{% assign low_number = | minus: 2 %}
{% endif %}
{% assign high_number = low_number | plus: 4 %}
{% assign high_number = high_number | at_most: paginator.total_pages %}
{% for page in (low_number..high_number) %}
{% if page == %}
<li class="page-item active">
<span class="page-link">
{{ page }}
{% else %}
<li class="page-item">
{% if page == 1 %}
<a href="{{ '/' | relative_url}}" class="page-link">
{{ page }}
{% else %}
<a href="{{ page | relative_url}}/" class="page-link">