# RDF/ATOM style for LiveJournal written in S2
# 
# Copyright (C) 2005 Nikolas Coukouma
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# This style is written in S2 and is intended to be used with LiveJournal or 
# LJ-derived sites. It must, at the very least, support the core layer. It 
# renders any view as an ATOM feed. The ATOM core is augmented with a variety 
# of schemas to supply more info (like moods and comments).
# It uses the following namespaces:
#
#    * atom - http://atomenabled.org/developers/api/atom-api-spec.php
#    * rdf - http://www.w3.org/1999/02/22-rdf-syntax-ns#
#    * rss - http://web.resource.org/rss/lj/1.0/
#    * lj - http://www.livejournal.org/rss/1.0/
#    * slash(dot/code) - http://web.resource.org/rss/1.0/modules/slash/
#    * blogcomments - http://philringnalda.com/ns/blogcomments/
# 
# The following information is included:
# 
#     * Per page (atom:feed):
#           o atom:title - title of the journal
#           o atom:tagline - "subtitle" of the journal
#           o atom:link - rel=alternate, href=url of the journal
#           o atom:generator - string stating that LiveJournal and this style were used to generate this feed
#           o rss:image - the default userpic of the journal being viewed (not included for the friends page)
#                 + rss:url - location of the userpic
#                 + rss:title - title of journal
#                 + rss:link - url of journal
#                 + rss:width - width of the image, in pixels
#                 + rss:width - height of the image, in pixels
#     * Per entry (atom:entry):
#           o atom:title - entry title, stripped of HTML
#           o atom:id - href=permalink to this entry
#           o atom:link - rel=alternate href=permalink to this entry
#           o atom:link - rel=prev href=previous entry
#           o atom:link - rel=next href=next entry
#           o atom:author - the author of the entry
#           o atom:content - type=text/html, mode=escaped, contains the post itself
#           o atom:issued - when this entry was first posted
#           o atom:modified - when it was modified. currently bogus and the same as issued
#           o lj:mood - mood string
#           o lj:music - music string
#           o slash:comments - number of comments
#           o blogcomments:comments - comments to this entry
#     * Per comment (blogcomments:comment):
#           o atom:title - comment title (subject), stripped of HTML
#           o blogcomments:name - username of the poster
#           o blogcomments:url - permalink to the comment
#           o blogcomments:date - when the comment was posted
#           o blogcomments:body - the actual text of the comment
#           o blogcomments:comments - any repplies to this comment
# 
#
# To use it on LiveJournal:
#
#   1. You must have a paid account
#   2. (This and the next two steps are optional if you're using LiveJournal) 
#      Go to your layers and create a new top-level layer of type layout
#   3. Click on edit
#   4. Replace the default stuff with the source.
#   5. Go to your styles
#   6. Create a new style. The name and language don't matter.
#   7. Select the layer you just created from the Layout dropdown and click Change.
#      OR, if you didn't create your own layer (skipped the last three steps)
#      select Other ... and enter the layer id 3770393.
#   8. Ignore the Language, Theme, and User dropdowns. Just click Save Changes
#   9. You can now view any journal page in this style by appending s2id=xxxxxxx 
#      to the query string (replace the x's with the number of the style you just created).
#      For example:
#        http://www.livejournal.com/users/atrustheotaku/?s2id=5922201
#        or
#        http://www.livejournal.com/users/atrustheotaku/?auth=digest&s2id=5922201
#
# If you find a bug or would like to make a suggestion, please e-mail me.
#
# This style is licensed under the LGPL.
# http://www.gnu.org/copyleft/lesser.html
#
# Created with the help of LiveJournal editing tools.
# http://www.livejournal.com/customize/advanced/

layerinfo type="layout";
layerinfo name="RDF (ATOM)";
layerinfo des="Displays an RDF feed of the requested view";
layerinfo author_name="Nikolas 'Atrus' Coukouma";
layerinfo author_email="atrus@REMOVEME atrus.org";
layerinfo source_viewable=1;
layerinfo is_public=1;

#inherited properties
property use page_recent_items;
property use page_friends_items;
property use IMGDIR;

# number of items to show on the page
set page_recent_items = 10;
set page_friends_items = 10;

# order in which to render entries and comments
property bool first_to_last;
set first_to_last = true;

# conform to W3C spec, as referenced by ATOM spec
# http://www.w3.org/TR/NOTE-datetime
property string dateformat;
set dateformat = "%%yyyy%%-%%mon%%-%%d%%T%%hh%%:%%min%%:%%sec%%+00:00";

function Page::print() {
# argh! still not commited
#	set_content_type( "text/xml" );
	var string strTitle;
	$strTitle = $this->title();

	"""<?xml version="1.0"?>
	<feed
	   xmlns="http://purl.org/atom/ns#"
	   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	   xmlns:rss="http://purl.org/rss/1.0/spec"
	   xmlns:lj="http://www.livejournal.org/rss/lj/1.0/"
	   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	   xmlns:blogcomments="http://philringnalda.com/ns/blogcomments/">
	<title>$this.global_title</title>
	<tagline>$this.global_subtitle</tagline>
	<link>$this.base_url</link>
	<generator>LiveJournal / LiveJournal.com / hacks.atrus.org / Nikolas Coukouma's ATOM style</generator>\n""";
	if ($this.view != "friends") {
"""	<rss:image>
		<rss:url>$this.journal.default_pic.url</url> 
		<rss:title>$this.global_title</title> 
		<rss:link rel="alternate" type="text/html" href="alternate$this.base_url" />
		<rss:width>$this.journal.default_pic.width</width> 
		<rss:height>$this.journal.default_pic.height</height> 
	</rss:image>\n""";
	}

	$this->print_body();

"</feed>";
}

function Page::print_body() {
# these properties MUST be specified according to the ATOM spec
# I'm just making them empty for lack of anything better to do
	"""
		<entry>
			<title />
			<link rel="alternate" />
			<author />
			<modified />
			<issued />
		</entry>\n""";
}

function RecentPage::print_body() {
	"""
		<entry>""";
	if ($*first_to_last)
	{
		foreach var Entry e (reverse $this.entries) { $this->print_entry($e); }
	} else {
		foreach var Entry e ($this.entries) { $this->print_entry($e); }
	}
	"""
	</entry>\n""";
}


function EntryPage::print_body() {
	"""
		<entry>""";
	if ($*first_to_last)
	{
		$this->print_entry($.entry);
		"""
			<blogcomments:comments>""";
		foreach var Comment c (reverse $.comments) { $this->print_comment($c); }
		"""
			</blogcomments:comments>""";
	} else {
		$this->print_entry($.entry);
		"""
			<blogcomments:comments>""";
		foreach var Comment c ($.comments) { $this->print_comment($c); }
		"""
			</blogcomments:comments>""";
	}
	"""
	</entry>\n""";
}

function FriendsPage::print_body() {
	"""
		<entry>""";
	if ($*first_to_last)
	{
		foreach var Entry e (reverse $this.entries) { $this->print_entry($e); }
	} else {
		foreach var Entry e ($this.entries) { $this->print_entry($e); }
	}
	"""
	</entry>\n""";
}

function DayPage::print_body() {
	"""
		<entry>""";
	if ($*first_to_last)
	{
		foreach var Entry e (reverse $this.entries) { $this->print_entry($e); }
	} else {
		foreach var Entry e ($this.entries) { $this->print_entry($e); }
	}
	"""
	</entry>\n""";
}

function Page::print_entry(Entry e) {
	var Link l;
	"""
			<id href="$e.permalink_url" />
			<link rel="alternate" href="$e.permalink_url" />
			<link rel="prev" href=\"""";
	$l = $e->get_link( "nav_prev" );
	print $l.url;
	"""\" />
			<link rel="next" href=\"""";
	$l = $e->get_link( "nav_next" );
	print $l.url;
	"""\" />
			<title>""";
	print $e->get_plain_subject();
	"""</title>
			<author>
				<name>$e.poster.username</name>
				<url>""";
	print $e.poster->base_url();
	"""</url>
			</author>
			<lj:mood>$e.metadata{"mood"}</lj:mood>
			<lj:music>$e.metadata{"music"}</lj:music>
			<content type="text/html" mode="escaped">""";
	
	print ehtml($e.text);
	"""</content>
				<issued>""";
	print $e.time->date_format( $*dateformat );
	"""</issued>
				<modified>""";
# bogus data, I'm sorry
	print $e.time->date_format( $*dateformat );
	"""</modified>
			<slash:comments>$e.comments.count</slash:comments>""";
}

function EntryPage::print_comment(Comment c) {
	"""
				<blogcomments:comment>
					<title>$c.subject</title>
					<blogcomments:name>$c.poster.username</blogcomments:name>
					<blogcomments:url rdf:resource=""";
	print "\"" + $c.poster->base_url() + "\"";
	""" />
					<blogcomments:date>""";
	print $c.time->date_format( $*dateformat );
	"""</blogcomments:date>
					<blogcomments:body type="text/html" mode="escaped">""";
	print ehtml($c.text);
	"""</blogcomments:body>\n""";
	if( (size $c.replies) > 0 ) {
		"""
			<blogcomments:comments>""";
	if ($*first_to_last)
	{
		foreach var Comment r ($c.replies) { $this->print_comment($r); }
	} else {
		foreach var Comment r ( reverse $c.replies) { $this->print_comment($r); }
	}
		"""
			</blogcomments:comments>""";
	}
	"""
				</blogcomments:comment>""";
}