Nathan Grigg

Filter App.net RSS

I was looking to make more room on my phone’s home screen, and I realized that my use of App.net had dwindled more than enough to remove it. I never post any more, but there are a couple of people I would still like to follow that don’t cross post to Twitter.

App.net has RSS feeds for every user, but they include both posts and replies. I only want to see posts. So I brushed off my primitive XSLT skills.

I wrote an XSLT program to delete RSS items that begin with @. While I was at it, I replaced each title with the user’s name, since the text of the post is also available in the description tag.

Here is the transformation that would filter my posts, if I had any:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <xsl:stylesheet version="1.0"
 3     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 4 
 5 <!-- Default identity transformation -->
 6 <xsl:template match="@*|node()">
 7     <xsl:copy>
 8         <xsl:apply-templates select="@*|node()"/>
 9     </xsl:copy>
10 </xsl:template>
11 
12 <!-- Replace title with my username -->
13 <xsl:template match="item/title/text()">nathangrigg</xsl:template>
14 
15 <!-- Remove completely items which are directed at other users.
16      The RSS feed has titles of the form @username: text of post. -->
17 <xsl:template match="item[contains(title, '@nathangrigg: @')]" />
18 </xsl:stylesheet>

Now I can use xsltproc to filter the RSS. In order to fill in the username automatically, I wrapped the XSLT program in a shell script that also invokes curl.

 1 #!/bin/bash
 2 set -o errexit
 3 set -o pipefail
 4 set -o nounset
 5 
 6 if (( $# != 1 )); then
 7     >&2 echo "USAGE: $0 username"
 8     exit 1
 9 fi
10 
11 username=$1
12 
13 xslt() {
14 cat << EOM
15 <?xml version="1.0" encoding="UTF-8"?>
16 <xsl:stylesheet version="1.0"
17     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
18 
19 <!-- Default identity transformation -->
20 <xsl:template match="@*|node()">
21     <xsl:copy>
22         <xsl:apply-templates select="@*|node()"/>
23     </xsl:copy>
24 </xsl:template>
25 <!-- Replace title with just the username -->
26 <xsl:template match="item/title/text()">$username</xsl:template>
27 <!-- Remove completely items which are directed at other users.
28         The RSS feed has titles of the form @username: text of post. -->
29 <xsl:template match="item[contains(title, '@$username: @')]" />
30 </xsl:stylesheet>
31 EOM
32 }
33 
34 rss() {
35     curl --silent --fail https://api.app.net/feed/rss/users/@$username/posts
36 }
37 
38 xsltproc <(xslt) <(rss)