9fbc187f2781094928e97988f66a95985d23f0a6
[tweeper.git] / rss_converter_facebook.com.xsl
1 <!--
2   Stylesheet to convert a Facebook public page to RSS.
3
4   Copyright (C) 2015  Antonio Ospite <ao2@ao2.it>
5
6   This file is part of tweeper.
7
8   This program is free software: you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation, either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 -->
21
22 <!--
23   Since June 23rd, 2015 facebook.com deprecated the RSS feed endpoint for public pages:
24   https://developers.facebook.com/docs/apps/changelog#v2_3_90_day_deprecations
25
26   They suggest to use the Graph API but they fail to mention that it does not
27   work anymore without authentication, so it cannot be considered an
28   _equivalent_ solution.
29
30   Luckily we've got Tweeper!
31 -->
32
33 <xsl:stylesheet version="1.0"
34     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
35     xmlns:php="http://php.net/xsl"
36     xsl:extension-element-prefixes="php"
37     exclude-result-prefixes="php">
38
39     <xsl:output method="xml" indent="yes"/>
40
41     <xsl:variable name="BaseURL">
42         <xsl:text>https://facebook.com</xsl:text>
43     </xsl:variable>
44
45     <xsl:template match="//div[contains(@class, 'userContentWrapper')]">
46         <xsl:variable name="item-content" select=".//div[contains(@class, 'userContent')]"/>
47         <xsl:variable name="item-permalink" select="concat($BaseURL, .//a[@target='']/@href)"/>
48         <item>
49             <title>
50                 <xsl:variable name="item-title" select="$item-content/p"/>
51                 <xsl:variable name="title-length" select="140"/>
52                 <!-- ellipsize, inspired from http://stackoverflow.com/questions/13622338 -->
53                 <xsl:choose>
54                     <xsl:when test="string-length($item-title) > $title-length">
55                         <xsl:variable name="truncated-length" select="$title-length - 3"/>
56                         <xsl:value-of select="substring($item-title, 1, $truncated-length)"/>
57                         <xsl:text>...</xsl:text>
58                     </xsl:when>
59                     <xsl:otherwise>
60                         <xsl:value-of select="$item-title"/>
61                     </xsl:otherwise>
62                 </xsl:choose>
63             </title>
64             <link>
65                 <xsl:value-of select="$item-permalink"/>
66             </link>
67             <guid>
68                 <xsl:value-of select="$item-permalink"/>
69             </guid>
70             <pubDate>
71                 <xsl:variable name="timestamp" select=".//abbr[@data-shorten]/@data-utime"/>
72                 <xsl:value-of select="php:functionString('Tweeper::epoch_to_gmdate', number($timestamp))"/>
73             </pubDate>
74             <description>
75                 <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
76                 <xsl:copy-of select="$item-content/node()"/>
77                 <xsl:copy-of select=".//div[@class='mtm']/node()"/>
78                 <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
79             </description>
80         </item>
81     </xsl:template>
82
83     <xsl:template match="/">
84         <xsl:variable name="channel-title" select="//title"/>
85         <xsl:variable name="channel-link" select="//div[contains(@class, 'userContentWrapper')][1]//a[1]/@href"/>
86
87         <rss version="2.0">
88             <xsl:attribute name="xml:base"><xsl:value-of select="$BaseURL" /></xsl:attribute>
89             <channel>
90                 <generator>Tweeper</generator>
91                 <title>
92                     <xsl:value-of select="$channel-title"/>
93                 </title>
94                 <link>
95                     <xsl:value-of select="$channel-link"/>
96                 </link>
97                 <description>
98                     <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
99                     <xsl:copy-of select="//div[@data-id='1']/node()"/>
100                     <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
101                 </description>
102                 <image>
103                     <title>
104                         <xsl:value-of select="$channel-title"/>
105                     </title>
106                     <link>
107                         <xsl:value-of select="$channel-link"/>
108                     </link>
109                     <url>
110                         <xsl:value-of select="//img[@class='profilePic img']/@src"/>
111                     </url>
112                 </image>
113                 <xsl:apply-templates select="//div[contains(@class, 'userContentWrapper')]"/>
114             </channel>
115         </rss>
116     </xsl:template>
117 </xsl:stylesheet>