harvester 0.8.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG.rdoc +45 -0
  2. data/README.rdoc +74 -0
  3. data/Rakefile +28 -0
  4. data/bin/harvester +13 -0
  5. data/bin/harvester-chart +5 -0
  6. data/bin/harvester-clock +35 -0
  7. data/bin/harvester-db +15 -0
  8. data/bin/harvester-fetch +5 -0
  9. data/bin/harvester-generate +5 -0
  10. data/bin/harvester-jabber +6 -0
  11. data/bin/harvester-new +25 -0
  12. data/bin/harvester-post +5 -0
  13. data/bin/harvester-run +14 -0
  14. data/collections.yaml +15 -0
  15. data/config.yaml +13 -0
  16. data/data/ent/HTMLlat1.ent +194 -0
  17. data/data/ent/HTMLspecial.ent +77 -0
  18. data/data/ent/HTMLsymbol.ent +241 -0
  19. data/data/sql/dbd-mysql-isotime.diff +11 -0
  20. data/data/sql/harvester-0.6-mysql.diff +59 -0
  21. data/data/sql/harvester-0.7-mysql.diff +39 -0
  22. data/data/sql/mysql/chart.sql +1 -0
  23. data/data/sql/mysql/create.table.enclosures.sql +9 -0
  24. data/data/sql/mysql/create.table.items.sql +8 -0
  25. data/data/sql/mysql/create.table.jabbersettings.sql +5 -0
  26. data/data/sql/mysql/create.table.jabbersubscriptions.sql +5 -0
  27. data/data/sql/mysql/create.table.sources.sql +9 -0
  28. data/data/sql/mysql/create.view.last48hours.sql +1 -0
  29. data/data/sql/postgresql/chart.sql +1 -0
  30. data/data/sql/postgresql/create.table.enclosures.sql +9 -0
  31. data/data/sql/postgresql/create.table.items.sql +8 -0
  32. data/data/sql/postgresql/create.table.jabbersettings.sql +5 -0
  33. data/data/sql/postgresql/create.table.jabbersubscriptions.sql +5 -0
  34. data/data/sql/postgresql/create.table.sources.sql +9 -0
  35. data/data/sql/postgresql/create.view.last48hours.sql +1 -0
  36. data/data/sql/sqlite3/chart.sql +1 -0
  37. data/data/sql/sqlite3/create.table.enclosures.sql +9 -0
  38. data/data/sql/sqlite3/create.table.items.sql +8 -0
  39. data/data/sql/sqlite3/create.table.jabbersettings.sql +5 -0
  40. data/data/sql/sqlite3/create.table.jabbersubscriptions.sql +5 -0
  41. data/data/sql/sqlite3/create.table.sources.sql +9 -0
  42. data/data/sql/sqlite3/create.view.last48hours.sql +1 -0
  43. data/data/templates/atom-all.xml +88 -0
  44. data/data/templates/atom.xml +88 -0
  45. data/data/templates/index.html +412 -0
  46. data/data/templates/rss-all.rdf +86 -0
  47. data/data/templates/rss.rdf +85 -0
  48. data/data/templates/static/harvester.css +365 -0
  49. data/data/templates/static/harvester.gif +0 -0
  50. data/data/templates/static/harvester_ie7.css +15 -0
  51. data/data/templates/static/harvester_lte_ie6.css +27 -0
  52. data/harvester.gemspec +35 -0
  53. data/lib/harvester.rb +132 -0
  54. data/lib/harvester/chart.rb +72 -0
  55. data/lib/harvester/db.rb +123 -0
  56. data/lib/harvester/fetch.rb +96 -0
  57. data/lib/harvester/generate.rb +152 -0
  58. data/lib/harvester/generator/entity_translator.rb +46 -0
  59. data/lib/harvester/generator/link_absolutizer.rb +39 -0
  60. data/lib/harvester/jabber.rb +443 -0
  61. data/lib/harvester/mrss.rb +355 -0
  62. data/lib/harvester/post.rb +19 -0
  63. metadata +237 -0
@@ -0,0 +1,5 @@
1
+ create table jabbersettings (
2
+ jid varchar(255) primary key,
3
+ respect_status boolean,
4
+ message_type varchar(16)
5
+ );
@@ -0,0 +1,5 @@
1
+ create table jabbersubscriptions (
2
+ jid varchar(255) not null,
3
+ collection varchar(255) not null,
4
+ unique (jid(166), collection(166))
5
+ );
@@ -0,0 +1,9 @@
1
+ create table sources (
2
+ collection varchar(255) not null,
3
+ rss varchar(255) not null,
4
+ last varchar(40),
5
+ title varchar(255),
6
+ link varchar(255),
7
+ description text,
8
+ unique (collection(166), rss(166))
9
+ );
@@ -0,0 +1 @@
1
+ create view last48hrs as select items.rss, items.title, items.link, sources.title as blogtitle, sources.collection from items, sources where items.rss = sources.rss and now() - interval '48 hour' < items.date order by date;
@@ -0,0 +1 @@
1
+ select date(items.date) as date,sources.collection from items left join sources on sources.rss=items.rss where date > now() - interval '14 days' and date < now() + interval '1 day' order by date
@@ -0,0 +1,9 @@
1
+ create table enclosures (
2
+ rss varchar(255) not null,
3
+ link varchar(255) not null,
4
+ href varchar(255) not null,
5
+ mime varchar(255),
6
+ title varchar(255),
7
+ length int,
8
+ unique (rss, link, href)
9
+ );
@@ -0,0 +1,8 @@
1
+ create table items (
2
+ rss varchar(255) not null,
3
+ title varchar(255),
4
+ link varchar(255),
5
+ date timestamp,
6
+ description text,
7
+ unique (rss, link)
8
+ );
@@ -0,0 +1,5 @@
1
+ create table jabbersettings (
2
+ jid varchar(255) primary key,
3
+ respect_status boolean,
4
+ message_type varchar(16)
5
+ );
@@ -0,0 +1,5 @@
1
+ create table jabbersubscriptions (
2
+ jid varchar(255) not null,
3
+ collection varchar(255) not null,
4
+ unique (jid, collection)
5
+ );
@@ -0,0 +1,9 @@
1
+ create table sources (
2
+ collection varchar(255) not null,
3
+ rss varchar(255) not null,
4
+ last varchar(40),
5
+ title varchar(255),
6
+ link varchar(255),
7
+ description text,
8
+ unique (collection, rss)
9
+ );
@@ -0,0 +1 @@
1
+ create view last48hrs as select items.rss, items.title, items.link, sources.title as blogtitle, sources.collection from items, sources where items.rss = sources.rss and now() - interval '48 hour' < items.date order by date;
@@ -0,0 +1 @@
1
+ select date(items.date) as date,sources.collection from items left join sources on sources.rss=items.rss where date > time('now', '-14 days') and date < time('now', '+1 day') order by date
@@ -0,0 +1,9 @@
1
+ create table enclosures (
2
+ rss varchar(255) not null,
3
+ link varchar(255) not null,
4
+ href varchar(255) not null,
5
+ mime varchar(255),
6
+ title varchar(255),
7
+ length int,
8
+ unique (rss, link, href)
9
+ );
@@ -0,0 +1,8 @@
1
+ create table items (
2
+ rss varchar(255) not null,
3
+ title varchar(255),
4
+ link varchar(255),
5
+ date timestamp,
6
+ description text,
7
+ unique (rss, link)
8
+ );
@@ -0,0 +1,5 @@
1
+ create table jabbersettings (
2
+ jid varchar(255) primary key,
3
+ respect_status boolean,
4
+ message_type varchar(16)
5
+ );
@@ -0,0 +1,5 @@
1
+ create table jabbersubscriptions (
2
+ jid varchar(255) not null,
3
+ collection varchar(255) not null,
4
+ unique (jid, collection)
5
+ );
@@ -0,0 +1,9 @@
1
+ create table sources (
2
+ collection varchar(255) not null,
3
+ rss varchar(255) not null,
4
+ last varchar(40),
5
+ title varchar(255),
6
+ link varchar(255),
7
+ description text,
8
+ unique (collection, rss)
9
+ );
@@ -0,0 +1 @@
1
+ create view last48hrs as select items.rss, items.title, items.link, sources.title as blogtitle, sources.collection from items, sources where items.rss = sources.rss and time('now', '-48 hour') < items.date order by date;
@@ -0,0 +1,88 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <xsl:stylesheet version="1.0"
3
+ xmlns="http://www.w3.org/2005/Atom"
4
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5
+ xmlns:crypto="http://exslt.org/crypto"
6
+ xmlns:hv="http://astroblog.spaceboyz.net/harvester/xslt-functions"
7
+ xmlns:date="http://exslt.org/dates-and-times"
8
+ exclude-result-prefixes="xsl hv crypto date">
9
+
10
+ <xsl:output method="xml"
11
+ version="1.0"
12
+ encoding="utf-8"
13
+ media-type="application/atom+xml"
14
+ indent="yes"/>
15
+
16
+ <xsl:template match="/collections">
17
+ <feed>
18
+ <title>Blog Harvester (all)</title>
19
+ <id>http://astroblog.spaceboyz.net/harvester/</id>
20
+ <link href="http://astroblog.spaceboyz.net/harvester/" rel="alternate" type="text/html"/>
21
+ <link href="http://astroblog.spaceboyz.net/harvester/atom-all.xml" rel="self" type="application/atom+xml"/>
22
+ <link href="http://astroblog.spaceboyz.net/harvester/rss-all.rdf" rel="alternate" type="application/rss+xml"/>
23
+
24
+ <subtitle type="xhtml">
25
+ <div xmlns="http://www.w3.org/1999/xhtml">
26
+ <p>
27
+ Blog Harvester sammelt Blogs von Menschen rund um Astro.
28
+ Enthalten sind:
29
+ </p>
30
+ <ul>
31
+ <xsl:for-each select="collection/feed">
32
+ <xsl:sort select="translate(title,
33
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
34
+ 'abcdefghijklmnopqrstuvwxyz')"/>
35
+ <li>
36
+ <a href="{link}"
37
+ title="{description}"><xsl:value-of select="title"/></a>
38
+ </li>
39
+ </xsl:for-each>
40
+ </ul>
41
+ <img src="chart.jpg"/>
42
+ </div>
43
+ </subtitle>
44
+ <updated><xsl:value-of select="date:date-time()"/></updated>
45
+
46
+ <xsl:variable name="collections" select="."/>
47
+ <xsl:for-each select="hv:collection-items('%')/item">
48
+ <xsl:variable name="rss" select="string(rss)"/>
49
+ <xsl:variable name="feed" select="$collections/collection/feed[rss=$rss]"/>
50
+ <entry>
51
+ <title><xsl:value-of select="concat($feed/title,': ',title)"/></title>
52
+ <id><xsl:value-of select="link"/></id>
53
+ <link href="{link}" rel="alternate" type="text/html"/>
54
+ <link href="{$feed/link}" rel="via" type="text/html"/>
55
+ <content type="xhtml">
56
+ <div xmlns="http://www.w3.org/1999/xhtml">
57
+ <xsl:value-of select="hv:item-description($rss, string(link))" disable-output-escaping="yes"/>
58
+ </div>
59
+ </content>
60
+ <updated><xsl:value-of select="date"/></updated>
61
+
62
+ <!-- Enclosures -->
63
+ <xsl:for-each select="hv:item-enclosures($rss, string(link))/enclosure">
64
+ <link rel="enclosure" href="{href}">
65
+ <xsl:if test="mime">
66
+ <xsl:attribute name="type">
67
+ <xsl:value-of select="mime"/>
68
+ </xsl:attribute>
69
+ </xsl:if>
70
+ <xsl:if test="string-length(title) &gt; 0">
71
+ <xsl:attribute name="title">
72
+ <xsl:value-of select="title"/>
73
+ </xsl:attribute>
74
+ </xsl:if>
75
+ <xsl:if test="number(length)">
76
+ <xsl:attribute name="length">
77
+ <xsl:value-of select="number(length)"/>
78
+ </xsl:attribute>
79
+ </xsl:if>
80
+ </link>
81
+ </xsl:for-each>
82
+
83
+ </entry>
84
+ </xsl:for-each>
85
+ </feed>
86
+ </xsl:template>
87
+
88
+ </xsl:stylesheet>
@@ -0,0 +1,88 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <xsl:stylesheet version="1.0"
3
+ xmlns="http://www.w3.org/2005/Atom"
4
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5
+ xmlns:crypto="http://exslt.org/crypto"
6
+ xmlns:hv="http://astroblog.spaceboyz.net/harvester/xslt-functions"
7
+ xmlns:date="http://exslt.org/dates-and-times"
8
+ exclude-result-prefixes="xsl hv crypto date">
9
+
10
+ <xsl:output method="xml"
11
+ version="1.0"
12
+ encoding="utf-8"
13
+ media-type="application/atom+xml"
14
+ indent="yes"/>
15
+
16
+ <xsl:template match="/collections">
17
+ <feed>
18
+ <title>Blog Harvester</title>
19
+ <id>http://astroblog.spaceboyz.net/harvester/</id>
20
+ <link href="http://astroblog.spaceboyz.net/harvester/" rel="alternate" type="text/html"/>
21
+ <link href="http://astroblog.spaceboyz.net/harvester/atom.xml" rel="self" type="application/atom+xml"/>
22
+ <link href="http://astroblog.spaceboyz.net/harvester/rss.rdf" rel="alternate" type="application/rss+xml"/>
23
+
24
+ <subtitle type="xhtml">
25
+ <div xmlns="http://www.w3.org/1999/xhtml">
26
+ <p>
27
+ Blog Harvester sammelt Blogs von Menschen rund um Astro.
28
+ Enthalten sind:
29
+ </p>
30
+ <ul>
31
+ <xsl:for-each select="collection[@name='blogs']/feed">
32
+ <xsl:sort select="translate(title,
33
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
34
+ 'abcdefghijklmnopqrstuvwxyz')"/>
35
+ <li>
36
+ <a href="{link}"
37
+ title="{description}"><xsl:value-of select="title"/></a>
38
+ </li>
39
+ </xsl:for-each>
40
+ </ul>
41
+ <img src="chart.jpg"/>
42
+ </div>
43
+ </subtitle>
44
+ <updated><xsl:value-of select="date:date-time()"/></updated>
45
+
46
+ <xsl:variable name="blogs" select="collection[@name='blogs']"/>
47
+ <xsl:for-each select="hv:collection-items('blogs')/item">
48
+ <xsl:variable name="rss" select="string(rss)"/>
49
+ <xsl:variable name="feed" select="$blogs/feed[rss=$rss]"/>
50
+ <entry>
51
+ <title><xsl:value-of select="concat($feed/title,': ',title)"/></title>
52
+ <id><xsl:value-of select="link"/></id>
53
+ <link href="{link}" rel="alternate" type="text/html"/>
54
+ <link href="{$feed/link}" rel="via" type="text/html"/>
55
+ <content type="xhtml">
56
+ <div xmlns="http://www.w3.org/1999/xhtml">
57
+ <xsl:value-of select="hv:item-description($rss, string(link))" disable-output-escaping="yes"/>
58
+ </div>
59
+ </content>
60
+ <updated><xsl:value-of select="date"/></updated>
61
+
62
+ <!-- Enclosures -->
63
+ <xsl:for-each select="hv:item-enclosures($rss, string(link))/enclosure">
64
+ <link rel="enclosure" href="{href}">
65
+ <xsl:if test="mime">
66
+ <xsl:attribute name="type">
67
+ <xsl:value-of select="mime"/>
68
+ </xsl:attribute>
69
+ </xsl:if>
70
+ <xsl:if test="string-length(title) &gt; 0">
71
+ <xsl:attribute name="title">
72
+ <xsl:value-of select="title"/>
73
+ </xsl:attribute>
74
+ </xsl:if>
75
+ <xsl:if test="number(length)">
76
+ <xsl:attribute name="length">
77
+ <xsl:value-of select="number(length)"/>
78
+ </xsl:attribute>
79
+ </xsl:if>
80
+ </link>
81
+ </xsl:for-each>
82
+
83
+ </entry>
84
+ </xsl:for-each>
85
+ </feed>
86
+ </xsl:template>
87
+
88
+ </xsl:stylesheet>
@@ -0,0 +1,412 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <xsl:stylesheet version="1.0"
3
+ xmlns="http://www.w3.org/1999/xhtml"
4
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5
+ xmlns:hv="http://astroblog.spaceboyz.net/harvester/xslt-functions"
6
+ xmlns:date="http://exslt.org/dates-and-times"
7
+ xmlns:str="http://exslt.org/strings"
8
+ exclude-result-prefixes="xsl hv date str">
9
+
10
+ <xsl:output method="xml"
11
+ version="1.0"
12
+ encoding="utf-8"
13
+ doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
14
+ doctype-system="DTD/xhtml1-strict.dtd"
15
+ indent="yes"/>
16
+
17
+
18
+ <xsl:template match="/collections">
19
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="de">
20
+ <head>
21
+ <title>Blog Harvester</title>
22
+ <link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href="atom.xml" />
23
+ <link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="rss.rdf" />
24
+ <link rel="alternate" type="application/atom+xml" title="ATOM 1.0 (all)" href="atom-all.xml" />
25
+ <link rel="alternate" type="application/rss+xml" title="RSS 2.0 (all)" href="rss-all.rdf" />
26
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
27
+ <link rel="stylesheet" type="text/css" href="harvester.css"/>
28
+ <link rel="shortcut icon" type="image/gif" href="harvester.gif"/>
29
+ <xsl:comment><![CDATA[[if IE 7]>
30
+ <link rel="stylesheet" type="text/css" href="harvester_ie7.css" />
31
+ <![endif]]]></xsl:comment>
32
+ <xsl:comment><![CDATA[[if lte IE 6]>
33
+ <link rel="stylesheet" type="text/css" href="harvester_lte_ie6.css" />
34
+ <![endif]]]></xsl:comment>
35
+ </head>
36
+
37
+ <body>
38
+ <div class="head">
39
+ <h1>Blog Harvester</h1>
40
+ <img src="chart.jpg" class="chart" alt="Harvested items per day"/>
41
+ </div>
42
+
43
+ <div class="tickers1">
44
+ <div class="ticker">
45
+ <h2>Harvesting</h2>
46
+ <ul class="tickerlinks">
47
+ <xsl:for-each select="collection[@name='blogs']/feed">
48
+ <xsl:sort select="translate(title, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
49
+ <li><a href="{link}" title="{description}"><xsl:value-of select="title"/></a></li>
50
+ </xsl:for-each>
51
+ </ul>
52
+ </div>
53
+ <div class="ticker">
54
+ <h2>Apropos</h2>
55
+ <p>
56
+ The Harvester is made of fresh flesh from the blogosphere,
57
+ clean design by Tigion
58
+ and hacked-together Ruby scripts by Astro,
59
+ improved by Neingeist, Josef and J-_-L.
60
+ </p>
61
+ </div>
62
+ <div class="ticker">
63
+ <h2>To be fed</h2>
64
+ <p>
65
+ Just blogs: <a href="atom.xml">ATOM 1.0</a> or <a href="rss.rdf">RSS 2.0</a>,
66
+ </p>
67
+ <p>
68
+ All collections: <a href="atom-all.xml">ATOM 1.0</a> or <a href="rss-all.rdf">RSS 2.0</a>
69
+ </p>
70
+ </div>
71
+ <div class="ticker">
72
+ <h2>Info</h2>
73
+ <p>...</p>
74
+ </div>
75
+ <div class="ticker">
76
+ <h2>Links</h2>
77
+ <ul class="tickerlinks">
78
+ <li><a href="http://ruby-lang.org/">Ruby</a></li>
79
+ </ul>
80
+ </div>
81
+
82
+ <xsl:call-template name="ticker-boxen">
83
+ <xsl:with-param name="collection" select="'ticker'"/>
84
+ </xsl:call-template>
85
+
86
+ <xsl:call-template name="ticker-boxen">
87
+ <xsl:with-param name="collection" select="'projects'"/>
88
+ </xsl:call-template>
89
+ </div>
90
+
91
+ <div class="tickers2">
92
+ <xsl:if test="hv:collection-items('photos')/item">
93
+ <div class="ticker">
94
+ <h2>Photos</h2>
95
+
96
+ <ul class="photos">
97
+ <xsl:for-each select="hv:collection-items('photos')/item">
98
+
99
+ <xsl:variable name="title" select="title"/>
100
+ <xsl:variable name="link" select="link"/>
101
+
102
+ <xsl:for-each select="hv:item-images(string(rss),
103
+ string(link))//img">
104
+ <li>
105
+ <a href="{$link}">
106
+ <img src="{@src}" title="{$title}" alt="{$title}"/>
107
+ </a>
108
+ </li>
109
+ </xsl:for-each>
110
+ </xsl:for-each>
111
+ </ul>
112
+ </div>
113
+ </xsl:if>
114
+
115
+ <xsl:call-template name="ticker-boxen">
116
+ <xsl:with-param name="collection" select="'links'"/>
117
+ </xsl:call-template>
118
+ </div>
119
+
120
+ <div class="tickers3">
121
+ <xsl:variable name="microblogs"
122
+ select="collection[@name='microblogs']"/>
123
+ <xsl:variable name="items"
124
+ select="hv:collection-items('microblogs', 100)"/>
125
+ <xsl:variable name="now"
126
+ select="date:date-time()"/>
127
+
128
+ <div class="ticker">
129
+ <h2>Microblogging — today</h2>
130
+ <ul>
131
+ <xsl:for-each select="$items/item">
132
+ <!--xsl:sort select="date" order="descending"/-->
133
+ <xsl:variable name="diff"
134
+ select="date:difference(date, $now)"/>
135
+ <xsl:if test="$diff = 'P0D' or
136
+ starts-with($diff, 'PT') or
137
+ starts-with($diff, '-P')">
138
+ <xsl:variable name="rss" select="string(rss)"/>
139
+ <xsl:variable name="feed"
140
+ select="$microblogs/feed[rss=$rss]"/>
141
+ <xsl:call-template name="microblog-entry">
142
+ <xsl:with-param name="feed" select="$feed"/>
143
+ <xsl:with-param name="entry" select="."/>
144
+ </xsl:call-template>
145
+ </xsl:if>
146
+ </xsl:for-each>
147
+ </ul>
148
+ </div>
149
+ <div class="ticker">
150
+ <h2>Microblogging — yesterday</h2>
151
+ <ul>
152
+ <xsl:for-each select="$items/item">
153
+ <!--xsl:sort select="date" order="descending"/-->
154
+ <xsl:if test="starts-with(date:difference(date, $now),
155
+ 'P1DT')">
156
+ <xsl:variable name="rss" select="string(rss)"/>
157
+ <xsl:variable name="feed"
158
+ select="$microblogs/feed[rss=$rss]"/>
159
+ <xsl:call-template name="microblog-entry">
160
+ <xsl:with-param name="feed" select="$feed"/>
161
+ <xsl:with-param name="entry" select="."/>
162
+ </xsl:call-template>
163
+ </xsl:if>
164
+ </xsl:for-each>
165
+ </ul>
166
+ </div>
167
+ <div class="ticker">
168
+ <h2>Microblogging — past</h2>
169
+ <ul>
170
+ <xsl:for-each select="hv:collection-items('microblogs')/item">
171
+ <!--xsl:sort select="date" order="descending"/-->
172
+ <xsl:variable name="diff"
173
+ select="date:difference(date, $now)"/>
174
+ <xsl:if test="not($diff = 'P0D') and
175
+ not(starts-with($diff, 'PT')) and
176
+ not(starts-with($diff, 'P1DT')) and
177
+ not(starts-with($diff, '-P'))">
178
+ <xsl:variable name="rss" select="string(rss)"/>
179
+ <xsl:variable name="feed"
180
+ select="$microblogs/feed[rss=$rss]"/>
181
+ <xsl:call-template name="microblog-entry">
182
+ <xsl:with-param name="feed" select="$feed"/>
183
+ <xsl:with-param name="entry" select="."/>
184
+ </xsl:call-template>
185
+ </xsl:if>
186
+ </xsl:for-each>
187
+ </ul>
188
+ </div>
189
+ </div>
190
+
191
+ <div class="hfeed">
192
+ <xsl:variable name="blogs" select="collection[@name='blogs']"/>
193
+
194
+ <xsl:for-each select="hv:collection-items('blogs')/item">
195
+ <xsl:variable name="rss" select="string(rss)"/>
196
+ <xsl:variable name="feed" select="$blogs/feed[rss=$rss]"/>
197
+ <div class="entry hentry">
198
+ <h2 class="blog-title">
199
+ <a href="{$feed/link}"><xsl:value-of select="$feed/title"/></a>
200
+ </h2>
201
+ <div class="entrydate published" title="{date}">
202
+ <xsl:value-of select="concat(date:day-in-month(date),'.',date:month-in-year(date),'. ',format-number(date:hour-in-day(date),'00'),':',format-number(date:minute-in-hour(date),'00'))"/>
203
+ </div>
204
+ <h3 class="entry-title"><a href="{link}" rel="bookmark"><xsl:value-of select="title"/></a></h3>
205
+ <div class="entrydesc entry-content">
206
+ <xsl:value-of select="hv:item-description($rss, string(link))" disable-output-escaping="yes"/>
207
+ </div>
208
+
209
+ <xsl:variable name="enclosures" select="hv:item-enclosures(string($rss), string(link))"/>
210
+ <xsl:if test="count($enclosures/enclosure) &gt; 0">
211
+ <ul>
212
+ <xsl:for-each select="$enclosures/enclosure">
213
+ <xsl:variable name="filename">
214
+ <xsl:call-template name="basename">
215
+ <xsl:with-param name="path" select="href"/>
216
+ </xsl:call-template>
217
+ </xsl:variable>
218
+ <li>
219
+ <xsl:choose>
220
+ <xsl:when test="string-length(string(title)) &gt; 0">
221
+ <xsl:value-of select="title"/>
222
+ (<a href="{href}" rel="enclosure"><xsl:value-of select="$filename"/></a>)
223
+ </xsl:when>
224
+ <xsl:otherwise>
225
+ <a href="{href}" rel="enclosure"><xsl:value-of select="$filename"/></a>
226
+ </xsl:otherwise>
227
+ </xsl:choose>
228
+
229
+ <xsl:text> </xsl:text>
230
+
231
+ <xsl:call-template name="format-enclosure-length">
232
+ <xsl:with-param name="length" select="number(length)"/>
233
+ </xsl:call-template>
234
+ </li>
235
+ </xsl:for-each>
236
+ </ul>
237
+ </xsl:if>
238
+
239
+ <div class="entryfoot"><a href="{link}" title="{link}">mehr&#8230;</a></div>
240
+ </div>
241
+ </xsl:for-each>
242
+ </div>
243
+
244
+ <p style="display:none"><a href="http://cthulhu.c3d2.de/~astro/badpit.html">E-Mail Address Index</a></p>
245
+ </body>
246
+ </html>
247
+ </xsl:template>
248
+
249
+ <xsl:template name="ticker-boxen">
250
+ <xsl:param name="collection"/>
251
+
252
+ <xsl:for-each select="collection[@name=$collection]/feed">
253
+ <xsl:sort select="translate(title, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
254
+ <div class="ticker hfeed">
255
+ <h2><a href="{link}"><xsl:value-of select="title"/></a></h2>
256
+ <ul class="tickerlinks">
257
+ <xsl:for-each select="hv:feed-items(string(rss), 8)/item">
258
+ <li class="hentry">
259
+ <xsl:choose>
260
+ <xsl:when test="string-length(title) &gt; 32">
261
+ <a href="{link}" title="{title}" rel="bookmark" class="entry-title"><xsl:value-of select="substring(title, 1, 30)"/>&#8230;</a>
262
+ </xsl:when>
263
+ <xsl:otherwise>
264
+ <a href="{link}" rel="bookmark" class="entry-title"><xsl:value-of select="title"/></a>
265
+ </xsl:otherwise>
266
+ </xsl:choose>
267
+ </li>
268
+ </xsl:for-each>
269
+ </ul>
270
+ </div>
271
+ </xsl:for-each>
272
+ </xsl:template>
273
+
274
+ <xsl:template name="format-enclosure-length">
275
+ <xsl:param name="length"/>
276
+
277
+ <xsl:if test="$length">
278
+ <xsl:choose>
279
+ <xsl:when test="$length &lt; 1024">
280
+ <xsl:value-of select="$length"/> Bytes
281
+ </xsl:when>
282
+ <xsl:when test="$length &lt; 1048576">
283
+ <xsl:value-of select="format-number($length div 1024, '0.0#')"/> KB
284
+ </xsl:when>
285
+ <xsl:when test="$length &lt; 1073741824">
286
+ <xsl:value-of select="format-number($length div 1048576, '0.0#')"/> MB
287
+ </xsl:when>
288
+ <xsl:otherwise>
289
+ <xsl:value-of select="format-number($length div 1073741824, '0.0#')"/> GB
290
+ </xsl:otherwise>
291
+ </xsl:choose>
292
+ </xsl:if>
293
+ </xsl:template>
294
+
295
+ <xsl:template name="basename">
296
+ <xsl:param name="path"/>
297
+
298
+ <xsl:choose>
299
+ <xsl:when test="contains($path, '/')">
300
+ <xsl:call-template name="basename">
301
+ <xsl:with-param name="path" select="substring-after($path, '/')"/>
302
+ </xsl:call-template>
303
+ </xsl:when>
304
+ <xsl:otherwise>
305
+ <xsl:value-of select="$path"/>
306
+ </xsl:otherwise>
307
+ </xsl:choose>
308
+ </xsl:template>
309
+
310
+ <xsl:template name="microblog-entry">
311
+ <xsl:param name="feed"/>
312
+ <xsl:param name="entry" select="."/>
313
+
314
+ <xsl:variable name="nick">
315
+ <xsl:choose>
316
+ <xsl:when test="contains($feed/title, ' timeline')">
317
+ <xsl:value-of select="substring-before(string($feed/title), ' timeline')"/>
318
+ </xsl:when>
319
+ <xsl:when test="contains($feed/title, 'Twitter / ')">
320
+ <xsl:value-of select="substring-after(string($feed/title), 'Twitter / ')"/>
321
+ </xsl:when>
322
+ <xsl:otherwise>
323
+ <xsl:value-of select="$feed/title"/>
324
+ </xsl:otherwise>
325
+ </xsl:choose>
326
+ </xsl:variable>
327
+ <xsl:variable name="text"
328
+ select="hv:item-description(string($entry/rss), string($entry/link))"/>
329
+ <li>
330
+ <xsl:if test="starts-with($entry/link,
331
+ 'http://identi.ca/notice/')">
332
+ <a href="http://identi.ca/{$nick}">
333
+ <img class="avatar" src="http://identi.ca/index.php?action=avatarbynickname&amp;nickname={$nick}&amp;size=24"
334
+ alt="avatar"/>
335
+ </a>
336
+ </xsl:if>
337
+ <xsl:if test="starts-with($entry/link,
338
+ 'http://twitter.com/')">
339
+ <a href="http://twitter.com/{$nick}">
340
+ <img class="avatar" src="http://spiurl.appspot.com/{$nick}"
341
+ alt="avatar"/>
342
+ </a>
343
+ </xsl:if>
344
+ <a class="nickname"
345
+ href="{$entry/link}"><xsl:value-of select="$nick"/></a>:
346
+ <xsl:choose>
347
+ <xsl:when test="starts-with($entry/link,
348
+ 'http://twitter.com/')">
349
+ <!-- Twitter does plaintext only -->
350
+ <xsl:call-template name="linkify">
351
+ <xsl:with-param name="s" select="substring-after($text, ': ')"/>
352
+ </xsl:call-template>
353
+ </xsl:when>
354
+ <xsl:otherwise>
355
+ <!-- identi.ca can haz linkz -->
356
+ <xsl:value-of select="$text"
357
+ disable-output-escaping="yes"/>
358
+ </xsl:otherwise>
359
+ </xsl:choose>
360
+ </li>
361
+ </xsl:template>
362
+
363
+ <xsl:template name="linkify">
364
+ <xsl:param name="s"/>
365
+
366
+ <xsl:choose>
367
+ <xsl:when test="contains($s, 'http://')">
368
+ <xsl:value-of select="substring-before($s, 'http://')"/>
369
+ <xsl:variable name="s2" select="concat('http://', substring-after($s, 'http://'))"/>
370
+ <xsl:choose>
371
+ <xsl:when test="contains($s2, ' ')">
372
+ <xsl:variable name="url" select="substring-before($s2, ' ')"/>
373
+ <a href="{$url}"><xsl:value-of select="$url"/></a>
374
+ <xsl:text> </xsl:text>
375
+ <xsl:call-template name="linkify">
376
+ <xsl:with-param name="s" select="substring-after($s2, ' ')"/>
377
+ </xsl:call-template>
378
+ </xsl:when>
379
+ <xsl:otherwise>
380
+ <a href="{$s2}"><xsl:value-of select="$s2"/></a>
381
+ </xsl:otherwise>
382
+ </xsl:choose>
383
+ </xsl:when>
384
+ <xsl:when test="contains($s, '#')">
385
+ <xsl:value-of select="substring-before($s, '#')"/>
386
+ <xsl:variable name="s2" select="concat('#', substring-after($s, '#'))"/>
387
+ <xsl:choose>
388
+ <xsl:when test="contains($s2, ' ')">
389
+ <xsl:variable name="hashtag" select="substring-before($s2, ' ')"/>
390
+ <a href="http://search.twitter.com/search?q={str:encode-uri($hashtag,
391
+ true())}">
392
+ <xsl:value-of select="$hashtag"/>
393
+ </a>
394
+ <xsl:text> </xsl:text>
395
+ <xsl:call-template name="linkify">
396
+ <xsl:with-param name="s" select="substring-after($s2, ' ')"/>
397
+ </xsl:call-template>
398
+ </xsl:when>
399
+ <xsl:otherwise>
400
+ <a href="http://search.twitter.com/search?q={str:encode-uri($s2, true())}">
401
+ <xsl:value-of select="$s2"/>
402
+ </a>
403
+ </xsl:otherwise>
404
+ </xsl:choose>
405
+ </xsl:when>
406
+ <xsl:otherwise>
407
+ <xsl:value-of select="$s"/>
408
+ </xsl:otherwise>
409
+ </xsl:choose>
410
+ </xsl:template>
411
+
412
+ </xsl:stylesheet>