Theme support
This commit is contained in:
parent
9fa9fb6117
commit
7cbc2e31bf
@ -2,6 +2,9 @@ xmlns = 'http://planet.intertwingly.net/'
|
|||||||
|
|
||||||
logger = None
|
logger = None
|
||||||
|
|
||||||
|
import config
|
||||||
|
config.__init__()
|
||||||
|
|
||||||
def getLogger(level):
|
def getLogger(level):
|
||||||
""" get a logger with the specified log level """
|
""" get a logger with the specified log level """
|
||||||
global logger
|
global logger
|
||||||
|
@ -11,7 +11,7 @@ Usage:
|
|||||||
config.load('config.ini')
|
config.load('config.ini')
|
||||||
|
|
||||||
# administrative / structural information
|
# administrative / structural information
|
||||||
print config.templates()
|
print config.template_files()
|
||||||
print config.feeds()
|
print config.feeds()
|
||||||
|
|
||||||
# planet wide configuration
|
# planet wide configuration
|
||||||
@ -37,6 +37,7 @@ def __init__():
|
|||||||
"""define the struture of an ini file"""
|
"""define the struture of an ini file"""
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
# underlying implementation
|
||||||
def get(section, option, default):
|
def get(section, option, default):
|
||||||
if section and parser.has_option(section, option):
|
if section and parser.has_option(section, option):
|
||||||
return parser.get(section, option)
|
return parser.get(section, option)
|
||||||
@ -49,6 +50,10 @@ def __init__():
|
|||||||
setattr(config, name, lambda default=default: get(None,name,default))
|
setattr(config, name, lambda default=default: get(None,name,default))
|
||||||
planet_predefined_options.append(name)
|
planet_predefined_options.append(name)
|
||||||
|
|
||||||
|
def define_planet_list(name):
|
||||||
|
setattr(config, name, lambda : get(None,name,'').split())
|
||||||
|
planet_predefined_options.append(name)
|
||||||
|
|
||||||
def define_tmpl(name, default):
|
def define_tmpl(name, default):
|
||||||
setattr(config, name, lambda section, default=default:
|
setattr(config, name, lambda section, default=default:
|
||||||
get(section,name,default))
|
get(section,name,default))
|
||||||
@ -63,25 +68,57 @@ def __init__():
|
|||||||
define_planet('cache_directory', "cache")
|
define_planet('cache_directory', "cache")
|
||||||
define_planet('log_level', "WARNING")
|
define_planet('log_level', "WARNING")
|
||||||
define_planet('feed_timeout', 20)
|
define_planet('feed_timeout', 20)
|
||||||
|
define_planet('date_format', "%B %d, %Y %I:%M %p")
|
||||||
|
define_planet('generator', 'Venus')
|
||||||
|
define_planet('generator_uri', 'http://intertwingly.net/code/venus/')
|
||||||
|
define_planet('owner_name', 'Anonymous Coward')
|
||||||
|
define_planet('owner_email', '')
|
||||||
|
define_planet('output_theme', '')
|
||||||
|
define_planet('output_dir', 'output')
|
||||||
|
|
||||||
|
define_planet_list('template_files')
|
||||||
|
define_planet_list('bill_of_materials')
|
||||||
|
define_planet_list('template_directories')
|
||||||
|
|
||||||
# template options
|
# template options
|
||||||
define_tmpl_int('days_per_page', 0)
|
define_tmpl_int('days_per_page', 0)
|
||||||
define_tmpl_int('items_per_page', 60)
|
define_tmpl_int('items_per_page', 60)
|
||||||
define_tmpl('encoding', 'utf-8')
|
define_tmpl('encoding', 'utf-8')
|
||||||
|
|
||||||
# prevent re-initialization
|
def load(config_file):
|
||||||
setattr(config, '__init__', lambda: None)
|
|
||||||
|
|
||||||
def load(file):
|
|
||||||
""" initialize and load a configuration"""
|
""" initialize and load a configuration"""
|
||||||
__init__()
|
|
||||||
global parser
|
global parser
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
parser.read(file)
|
parser.read(config_file)
|
||||||
|
|
||||||
def template_files():
|
if parser.has_option('Planet', 'output_theme'):
|
||||||
""" list the templates defined """
|
theme = parser.get('Planet', 'output_theme')
|
||||||
return parser.get('Planet','template_files').split(' ')
|
for path in ("", os.path.join(sys.path[0],'themes')):
|
||||||
|
theme_dir = os.path.join(path,theme)
|
||||||
|
theme_file = os.path.join(theme_dir,'config.ini')
|
||||||
|
if os.path.exists(theme_file):
|
||||||
|
# initial search list for theme directories
|
||||||
|
dirs = [theme_dir]
|
||||||
|
if parser.has_option('Planet', 'template_directories'):
|
||||||
|
dirs.insert(0,parser.get('Planet', 'template_directories'))
|
||||||
|
|
||||||
|
# read in the theme
|
||||||
|
parser = ConfigParser()
|
||||||
|
parser.read(theme_file)
|
||||||
|
|
||||||
|
# complete search list for theme directories
|
||||||
|
if parser.has_option('Planet', 'template_directories'):
|
||||||
|
dirs += [os.path.join(theme_dir,dir) for dir in
|
||||||
|
parser.get('Planet', 'template_directories').split()]
|
||||||
|
|
||||||
|
# merge configurations, allowing current one to override theme
|
||||||
|
parser.read(config_file)
|
||||||
|
parser.set('Planet', 'template_directories', ' '.join(dirs))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
import config, planet
|
||||||
|
log = planet.getLogger(config.log_level())
|
||||||
|
log.error('Unable to find theme %s', theme)
|
||||||
|
|
||||||
def cache_sources_directory():
|
def cache_sources_directory():
|
||||||
if parser.has_option('Planet', 'cache_sources_directory'):
|
if parser.has_option('Planet', 'cache_sources_directory'):
|
||||||
|
@ -18,7 +18,7 @@ from xml.sax.saxutils import escape
|
|||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from BeautifulSoup import BeautifulSoup
|
from BeautifulSoup import BeautifulSoup
|
||||||
from xml.parsers.expat import ExpatError
|
from xml.parsers.expat import ExpatError
|
||||||
import planet
|
import planet, config
|
||||||
|
|
||||||
illegal_xml_chars = re.compile("[\x01-\x08\x0B\x0C\x0E-\x1F]")
|
illegal_xml_chars = re.compile("[\x01-\x08\x0B\x0C\x0E-\x1F]")
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ def createTextElement(parent, name, value):
|
|||||||
xelement = xdoc.createElement(name)
|
xelement = xdoc.createElement(name)
|
||||||
xelement.appendChild(xdoc.createTextNode(value))
|
xelement.appendChild(xdoc.createTextNode(value))
|
||||||
parent.appendChild(xelement)
|
parent.appendChild(xelement)
|
||||||
|
return xelement
|
||||||
|
|
||||||
def invalidate(c):
|
def invalidate(c):
|
||||||
""" replace invalid characters """
|
""" replace invalid characters """
|
||||||
@ -98,7 +99,9 @@ def date(xentry, name, parsed):
|
|||||||
""" insert a date-formated element into the entry """
|
""" insert a date-formated element into the entry """
|
||||||
if not parsed: return
|
if not parsed: return
|
||||||
formatted = time.strftime("%Y-%m-%dT%H:%M:%SZ", parsed)
|
formatted = time.strftime("%Y-%m-%dT%H:%M:%SZ", parsed)
|
||||||
createTextElement(xentry, name, formatted)
|
xdate = createTextElement(xentry, name, formatted)
|
||||||
|
formatted = time.strftime(config.date_format(), parsed)
|
||||||
|
xdate.setAttribute('planet:format', formatted)
|
||||||
|
|
||||||
def author(xentry, name, detail):
|
def author(xentry, name, detail):
|
||||||
""" insert an author-like element into the entry """
|
""" insert an author-like element into the entry """
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
""" Splice together a planet from a cache of feed entries """
|
""" Splice together a planet from a cache of feed entries """
|
||||||
import glob, os
|
import glob, os, time, shutil
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import planet, config, feedparser, reconstitute
|
import planet, config, feedparser, reconstitute
|
||||||
from reconstitute import createTextElement
|
from reconstitute import createTextElement, date
|
||||||
from spider import filename
|
from spider import filename
|
||||||
|
|
||||||
def splice(configFile):
|
def splice(configFile):
|
||||||
@ -11,6 +11,7 @@ def splice(configFile):
|
|||||||
config.load(configFile)
|
config.load(configFile)
|
||||||
log = planet.getLogger(config.log_level())
|
log = planet.getLogger(config.log_level())
|
||||||
|
|
||||||
|
log.info("Loading cached data")
|
||||||
cache = config.cache_directory()
|
cache = config.cache_directory()
|
||||||
dir=[(os.stat(file).st_mtime,file) for file in glob.glob(cache+"/*")
|
dir=[(os.stat(file).st_mtime,file) for file in glob.glob(cache+"/*")
|
||||||
if not os.path.isdir(file)]
|
if not os.path.isdir(file)]
|
||||||
@ -18,17 +19,20 @@ def splice(configFile):
|
|||||||
dir.reverse()
|
dir.reverse()
|
||||||
|
|
||||||
items=max([config.items_per_page(templ)
|
items=max([config.items_per_page(templ)
|
||||||
for templ in config.template_files()])
|
for templ in config.template_files() or ['Planet']])
|
||||||
|
|
||||||
doc = minidom.parseString('<feed xmlns="http://www.w3.org/2005/Atom"/>')
|
doc = minidom.parseString('<feed xmlns="http://www.w3.org/2005/Atom"/>')
|
||||||
feed = doc.documentElement
|
feed = doc.documentElement
|
||||||
|
|
||||||
# insert Google/LiveJournal's noindex
|
|
||||||
feed.setAttribute('indexing:index','no')
|
|
||||||
feed.setAttribute('xmlns:indexing','urn:atom-extension:indexing')
|
|
||||||
|
|
||||||
# insert feed information
|
# insert feed information
|
||||||
createTextElement(feed, 'title', config.name())
|
createTextElement(feed, 'title', config.name())
|
||||||
|
date(feed, 'updated', time.gmtime())
|
||||||
|
gen = createTextElement(feed, 'generator', config.generator())
|
||||||
|
gen.setAttribute('uri', config.generator_uri())
|
||||||
|
author = doc.createElement('author')
|
||||||
|
createTextElement(author, 'name', config.owner_name())
|
||||||
|
createTextElement(author, 'email', config.owner_email())
|
||||||
|
feed.appendChild(author)
|
||||||
|
|
||||||
# insert entry information
|
# insert entry information
|
||||||
for mtime,file in dir[:items]:
|
for mtime,file in dir[:items]:
|
||||||
@ -47,3 +51,75 @@ def splice(configFile):
|
|||||||
feed.appendChild(xdoc.documentElement)
|
feed.appendChild(xdoc.documentElement)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
def apply(doc):
|
||||||
|
output_dir = config.output_dir()
|
||||||
|
if not os.path.exists(output_dir): os.makedirs(output_dir)
|
||||||
|
log = planet.getLogger(config.log_level())
|
||||||
|
|
||||||
|
try:
|
||||||
|
# if available, use the python interface to libxslt
|
||||||
|
import libxml2
|
||||||
|
import libxslt
|
||||||
|
dom = libxml2.parseDoc(doc)
|
||||||
|
docfile = None
|
||||||
|
except:
|
||||||
|
# otherwise, use the command line interface
|
||||||
|
dom = None
|
||||||
|
import warnings
|
||||||
|
warnings.simplefilter('ignore', RuntimeWarning)
|
||||||
|
docfile = os.tmpnam()
|
||||||
|
file = open(docfile,'w')
|
||||||
|
file.write(doc)
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
# Go-go-gadget-template
|
||||||
|
for template_file in config.template_files():
|
||||||
|
for template_dir in config.template_directories():
|
||||||
|
template_resolved = os.path.join(template_dir, template_file)
|
||||||
|
if os.path.exists(template_resolved): break
|
||||||
|
else:
|
||||||
|
log.error("Unable to locate template %s", template_file)
|
||||||
|
continue
|
||||||
|
|
||||||
|
base,ext = os.path.splitext(os.path.basename(template_resolved))
|
||||||
|
if ext != '.xslt':
|
||||||
|
log.warning("Skipping template %s", template_resolved)
|
||||||
|
continue
|
||||||
|
|
||||||
|
log.info("Processing template %s", template_resolved)
|
||||||
|
output_file = os.path.join(output_dir, base)
|
||||||
|
if dom:
|
||||||
|
styledoc = libxml2.parseFile(template_resolved)
|
||||||
|
style = libxslt.parseStylesheetDoc(styledoc)
|
||||||
|
result = style.applyStylesheet(dom, None)
|
||||||
|
log.info("Writing %s", output_file)
|
||||||
|
style.saveResultToFilename(output_file, result, 0)
|
||||||
|
style.freeStylesheet()
|
||||||
|
result.freeDoc()
|
||||||
|
else:
|
||||||
|
log.info("Writing %s", output_file)
|
||||||
|
os.system('xsltproc %s %s > %s' %
|
||||||
|
(template_resolved, docfile, output_file))
|
||||||
|
|
||||||
|
if dom: dom.freeDoc()
|
||||||
|
if docfile: os.unlink(docfile)
|
||||||
|
|
||||||
|
# Process bill of materials
|
||||||
|
for copy_file in config.bill_of_materials():
|
||||||
|
dest = os.path.join(output_dir, copy_file)
|
||||||
|
for template_dir in config.template_directories():
|
||||||
|
source = os.path.join(template_dir, copy_file)
|
||||||
|
if os.path.exists(source): break
|
||||||
|
else:
|
||||||
|
log.error('Unable to locate %s', copy_file)
|
||||||
|
continue
|
||||||
|
|
||||||
|
mtime = os.stat(source).st_mtime
|
||||||
|
if not os.path.exists(dest) or os.stat(dest).st_mtime < mtime:
|
||||||
|
dest_dir = os.path.split(dest)[0]
|
||||||
|
if not os.path.exists(dest_dir): os.makedirs(dest_dir)
|
||||||
|
|
||||||
|
log.info("Copying %s to %s", source, dest)
|
||||||
|
shutil.copyfile(source, dest)
|
||||||
|
shutil.copystat(source, dest)
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import glob, trace, unittest
|
import glob, trace, unittest, os, sys
|
||||||
|
|
||||||
|
# start in a consistent, predictable location
|
||||||
|
os.chdir(sys.path[0])
|
||||||
|
|
||||||
# find all of the planet test modules
|
# find all of the planet test modules
|
||||||
modules = map(trace.fullmodname, glob.glob('tests/test_*.py'))
|
modules = map(trace.fullmodname, glob.glob(os.path.join('tests', 'test_*.py')))
|
||||||
|
|
||||||
# load all of the tests into a suite
|
# load all of the tests into a suite
|
||||||
suite = unittest.TestLoader().loadTestsFromNames(modules)
|
suite = unittest.TestLoader().loadTestsFromNames(modules)
|
||||||
|
@ -13,10 +13,7 @@ if __name__ == '__main__':
|
|||||||
# at the moment, we don't have template support, so we cheat and
|
# at the moment, we don't have template support, so we cheat and
|
||||||
# simply insert a XSLT processing instruction
|
# simply insert a XSLT processing instruction
|
||||||
doc = splice.splice(sys.argv[1])
|
doc = splice.splice(sys.argv[1])
|
||||||
pi = doc.createProcessingInstruction(
|
splice.apply(doc.toxml('utf-8'))
|
||||||
'xml-stylesheet','type="text/xsl" href="planet.xslt"')
|
|
||||||
doc.insertBefore(pi, doc.firstChild)
|
|
||||||
print doc.toxml('utf-8')
|
|
||||||
else:
|
else:
|
||||||
print "Usage:"
|
print "Usage:"
|
||||||
print " python %s config.ini" % sys.argv[0]
|
print " python %s config.ini" % sys.argv[0]
|
||||||
|
42
tests/capture.py
Executable file
42
tests/capture.py
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
While unit tests are intended to be independently executable, it often
|
||||||
|
is helpful to ensure that some downstream tasks can be run with the
|
||||||
|
exact output produced by upstream tasks.
|
||||||
|
|
||||||
|
This script captures such output. It should be run whenever there is
|
||||||
|
a major change in the contract between stages
|
||||||
|
"""
|
||||||
|
|
||||||
|
import shutil, os, sys
|
||||||
|
|
||||||
|
# move up a directory
|
||||||
|
sys.path.insert(1, os.path.split(sys.path[0])[0])
|
||||||
|
os.chdir(sys.path[1])
|
||||||
|
|
||||||
|
# copy spider output to splice input
|
||||||
|
from planet import spider
|
||||||
|
spider.spiderPlanet('tests/data/spider/config.ini')
|
||||||
|
if os.path.exists('tests/data/splice/cache'):
|
||||||
|
shutil.rmtree('tests/data/splice/cache')
|
||||||
|
shutil.move('tests/work/spider/cache', 'tests/data/splice/cache')
|
||||||
|
|
||||||
|
source=open('tests/data/spider/config.ini')
|
||||||
|
dest1=open('tests/data/splice/config.ini', 'w')
|
||||||
|
dest1.write(source.read().replace('/work/spider/', '/data/splice/'))
|
||||||
|
dest1.close()
|
||||||
|
|
||||||
|
source.seek(0)
|
||||||
|
dest2=open('tests/data/apply/config.ini', 'w')
|
||||||
|
dest2.write(source.read().replace('[Planet]', '''[Planet]
|
||||||
|
output_theme = asf
|
||||||
|
output_dir = tests/work/apply'''))
|
||||||
|
dest2.close()
|
||||||
|
source.close()
|
||||||
|
|
||||||
|
# copy splice output to apply input
|
||||||
|
from planet import splice
|
||||||
|
file=open('tests/data/apply/feed.xml', 'w')
|
||||||
|
file.write(splice.splice('tests/data/splice/config.ini').toxml('utf-8'))
|
||||||
|
file.close()
|
17
tests/data/apply/config.ini
Normal file
17
tests/data/apply/config.ini
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[Planet]
|
||||||
|
output_theme = asf
|
||||||
|
output_dir = tests/work/apply
|
||||||
|
name = test planet
|
||||||
|
cache_directory = tests/work/spider/cache
|
||||||
|
|
||||||
|
[tests/data/spider/testfeed0.atom]
|
||||||
|
name = not found
|
||||||
|
|
||||||
|
[tests/data/spider/testfeed1b.atom]
|
||||||
|
name = one
|
||||||
|
|
||||||
|
[tests/data/spider/testfeed2.atom]
|
||||||
|
name = two
|
||||||
|
|
||||||
|
[tests/data/spider/testfeed3.rss]
|
||||||
|
name = three
|
215
tests/data/apply/feed.xml
Normal file
215
tests/data/apply/feed.xml
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/"><title>test planet</title><updated planet:format="August 21, 2006 12:54 PM">2006-08-21T12:54:31Z</updated><generator uri="http://intertwingly.net/code/venus/">Venus</generator><author><name>Anonymous Coward</name></author><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed3/2</id>
|
||||||
|
<link href="http://example.com/2" rel="alternate" type="text/html"/>
|
||||||
|
<title>Venus</title>
|
||||||
|
<summary>the Morning Star</summary>
|
||||||
|
<updated planet:format="August 21, 2006 12:54 PM">2006-08-21T12:54:31Z</updated>
|
||||||
|
<source>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss" rel="alternate" type="text/html"/>
|
||||||
|
<link href="tests/data/spider/testfeed3.rss" rel="self" type="application/atom+xml"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<planet:name>three</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>http://example.com/4</id>
|
||||||
|
<link href="http://example.com/4" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mars</title>
|
||||||
|
<summary>the Red Planet</summary>
|
||||||
|
<updated planet:format="August 21, 2006 12:54 PM">2006-08-21T12:54:31Z</updated>
|
||||||
|
<source>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss" rel="alternate" type="text/html"/>
|
||||||
|
<link href="tests/data/spider/testfeed3.rss" rel="self" type="application/atom+xml"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<planet:name>three</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1/2</id>
|
||||||
|
<link href="http://example.com/2" rel="alternate" type="text/html"/>
|
||||||
|
<title>Venus</title>
|
||||||
|
<content>the Jewel of the Sky</content>
|
||||||
|
<updated planet:format="February 02, 2006 12:00 AM">2006-02-02T00:00:00Z</updated>
|
||||||
|
<published planet:format="January 02, 2006 12:00 AM">2006-01-02T00:00:00Z</published>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed1a.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>one</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2/4</id>
|
||||||
|
<link href="http://example.com/4" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mars</title>
|
||||||
|
<content>the Red Planet</content>
|
||||||
|
<updated planet:format="January 04, 2006 12:00 AM">2006-01-04T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed2.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>two</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1/4</id>
|
||||||
|
<link href="http://example.com/4" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mars</title>
|
||||||
|
<content>the Red Planet</content>
|
||||||
|
<updated planet:format="January 04, 2006 12:00 AM">2006-01-04T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed1a.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>one</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2/3</id>
|
||||||
|
<link href="http://example.com/3" rel="alternate" type="text/html"/>
|
||||||
|
<title>Earth</title>
|
||||||
|
<content>the Blue Planet</content>
|
||||||
|
<updated planet:format="January 03, 2006 12:00 AM">2006-01-03T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed2.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>two</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1/3</id>
|
||||||
|
<link href="http://example.com/3" rel="alternate" type="text/html"/>
|
||||||
|
<title>Earth</title>
|
||||||
|
<content>the Blue Planet</content>
|
||||||
|
<updated planet:format="January 03, 2006 12:00 AM">2006-01-03T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed1a.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>one</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>http://example.com/3</id>
|
||||||
|
<link href="http://example.com/3" rel="alternate" type="text/html"/>
|
||||||
|
<title>Earth</title>
|
||||||
|
<summary>the Blue Planet</summary>
|
||||||
|
<updated planet:format="January 03, 2006 12:00 AM">2006-01-03T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss" rel="alternate" type="text/html"/>
|
||||||
|
<link href="tests/data/spider/testfeed3.rss" rel="self" type="application/atom+xml"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<planet:name>three</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2/2</id>
|
||||||
|
<link href="http://example.com/2" rel="alternate" type="text/html"/>
|
||||||
|
<title>Venus</title>
|
||||||
|
<content>the Morning Star</content>
|
||||||
|
<updated planet:format="January 02, 2006 12:00 AM">2006-01-02T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed2.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>two</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed3/1</id>
|
||||||
|
<link href="http://example.com/1" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mercury</title>
|
||||||
|
<summary>Messenger of the Roman Gods</summary>
|
||||||
|
<updated planet:format="January 01, 2006 12:00 AM">2006-01-01T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss" rel="alternate" type="text/html"/>
|
||||||
|
<link href="tests/data/spider/testfeed3.rss" rel="self" type="application/atom+xml"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<planet:name>three</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2/1</id>
|
||||||
|
<link href="http://example.com/1" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mercury</title>
|
||||||
|
<content>Messenger of the Roman Gods</content>
|
||||||
|
<updated planet:format="January 01, 2006 12:00 AM">2006-01-01T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed2.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>two</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><entry xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/">
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1/1</id>
|
||||||
|
<link href="http://example.com/1" rel="alternate" type="text/html"/>
|
||||||
|
<title>Mercury</title>
|
||||||
|
<content>Messenger of the Roman Gods</content>
|
||||||
|
<updated planet:format="January 01, 2006 12:00 AM">2006-01-01T00:00:00Z</updated>
|
||||||
|
<source>
|
||||||
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
|
<author>
|
||||||
|
<name>Sam Ruby</name>
|
||||||
|
<email>rubys@intertwingly.net</email>
|
||||||
|
<uri>http://www.intertwingly.net/blog/</uri>
|
||||||
|
</author>
|
||||||
|
<link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed1a.atom" rel="self" type="application/atom+xml"/>
|
||||||
|
<link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/>
|
||||||
|
<subtitle>It’s just data</subtitle>
|
||||||
|
<title>Sam Ruby</title>
|
||||||
|
<updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated>
|
||||||
|
<planet:name>one</planet:name>
|
||||||
|
</source>
|
||||||
|
</entry><planet:source xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/"><id>tag:planet.intertwingly.net,2006:testfeed2</id><author><name>Sam Ruby</name><email>rubys@intertwingly.net</email><uri>http://www.intertwingly.net/blog/</uri></author><link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed2.atom" rel="self" type="application/atom+xml"/><link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/><subtitle>It’s just data</subtitle><title>Sam Ruby</title><updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated><planet:name>two</planet:name></planet:source><planet:source xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/"><link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss" rel="alternate" type="text/html"/><link href="tests/data/spider/testfeed3.rss" rel="self" type="application/atom+xml"/><subtitle>It’s just data</subtitle><title>Sam Ruby</title><planet:name>three</planet:name></planet:source><planet:source xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/"><id>tag:planet.intertwingly.net,2006:testfeed1</id><author><name>Sam Ruby</name><email>rubys@intertwingly.net</email><uri>http://www.intertwingly.net/blog/</uri></author><link href="http://intertwingly.net/code/venus/tests/data/spider/testfeed1a.atom" rel="self" type="application/atom+xml"/><link href="http://www.intertwingly.net/blog/" rel="alternate" type="text/html"/><subtitle>It’s just data</subtitle><title>Sam Ruby</title><updated planet:format="June 17, 2006 12:15 AM">2006-06-17T00:15:18Z</updated><planet:name>one</planet:name></planet:source></feed>
|
14
tests/data/config/themed.ini
Normal file
14
tests/data/config/themed.ini
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[Planet]
|
||||||
|
name = Test Configuration
|
||||||
|
output_theme = asf
|
||||||
|
items_per_page = 50
|
||||||
|
template_directories = /foo /bar
|
||||||
|
|
||||||
|
[index.html.xslt]
|
||||||
|
days_per_page = 7
|
||||||
|
|
||||||
|
[feed1]
|
||||||
|
name = one
|
||||||
|
|
||||||
|
[feed2]
|
||||||
|
name = two
|
@ -1,6 +1,6 @@
|
|||||||
[Planet]
|
[Planet]
|
||||||
|
name = test planet
|
||||||
cache_directory = tests/work/spider/cache
|
cache_directory = tests/work/spider/cache
|
||||||
template_files =
|
|
||||||
|
|
||||||
[tests/data/spider/testfeed0.atom]
|
[tests/data/spider/testfeed0.atom]
|
||||||
name = not found
|
name = not found
|
||||||
|
2
tests/data/splice/cache/example.com,3
vendored
2
tests/data/splice/cache/example.com,3
vendored
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
||||||
<title>Earth</title>
|
<title>Earth</title>
|
||||||
<summary>the Blue Planet</summary>
|
<summary>the Blue Planet</summary>
|
||||||
<updated>2006-01-03T00:00:00Z</updated>
|
<updated planet:format='January 03, 2006 12:00 AM'>2006-01-03T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
||||||
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
||||||
|
2
tests/data/splice/cache/example.com,4
vendored
2
tests/data/splice/cache/example.com,4
vendored
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
||||||
<title>Mars</title>
|
<title>Mars</title>
|
||||||
<summary>the Red Planet</summary>
|
<summary>the Red Planet</summary>
|
||||||
<updated>2006-08-18T18:30:50Z</updated>
|
<updated planet:format='August 21, 2006 12:54 PM'>2006-08-21T12:54:31Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
||||||
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
||||||
<title>Mercury</title>
|
<title>Mercury</title>
|
||||||
<content>Messenger of the Roman Gods</content>
|
<content>Messenger of the Roman Gods</content>
|
||||||
<updated>2006-01-01T00:00:00Z</updated>
|
<updated planet:format='January 01, 2006 12:00 AM'>2006-01-01T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>one</planet:name>
|
<planet:name>one</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
||||||
<title>Venus</title>
|
<title>Venus</title>
|
||||||
<content>the Jewel of the Sky</content>
|
<content>the Jewel of the Sky</content>
|
||||||
<updated>2006-02-02T00:00:00Z</updated>
|
<updated planet:format='February 02, 2006 12:00 AM'>2006-02-02T00:00:00Z</updated>
|
||||||
<published>2006-01-02T00:00:00Z</published>
|
<published planet:format='January 02, 2006 12:00 AM'>2006-01-02T00:00:00Z</published>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
<author>
|
<author>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>one</planet:name>
|
<planet:name>one</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
||||||
<title>Earth</title>
|
<title>Earth</title>
|
||||||
<content>the Blue Planet</content>
|
<content>the Blue Planet</content>
|
||||||
<updated>2006-01-03T00:00:00Z</updated>
|
<updated planet:format='January 03, 2006 12:00 AM'>2006-01-03T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>one</planet:name>
|
<planet:name>one</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
||||||
<title>Mars</title>
|
<title>Mars</title>
|
||||||
<content>the Red Planet</content>
|
<content>the Red Planet</content>
|
||||||
<updated>2006-01-04T00:00:00Z</updated>
|
<updated planet:format='January 04, 2006 12:00 AM'>2006-01-04T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed1</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>one</planet:name>
|
<planet:name>one</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
||||||
<title>Mercury</title>
|
<title>Mercury</title>
|
||||||
<content>Messenger of the Roman Gods</content>
|
<content>Messenger of the Roman Gods</content>
|
||||||
<updated>2006-01-01T00:00:00Z</updated>
|
<updated planet:format='January 01, 2006 12:00 AM'>2006-01-01T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>two</planet:name>
|
<planet:name>two</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
||||||
<title>Venus</title>
|
<title>Venus</title>
|
||||||
<content>the Morning Star</content>
|
<content>the Morning Star</content>
|
||||||
<updated>2006-01-02T00:00:00Z</updated>
|
<updated planet:format='January 02, 2006 12:00 AM'>2006-01-02T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>two</planet:name>
|
<planet:name>two</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
<link href='http://example.com/3' type='text/html' rel='alternate'/>
|
||||||
<title>Earth</title>
|
<title>Earth</title>
|
||||||
<content>the Blue Planet</content>
|
<content>the Blue Planet</content>
|
||||||
<updated>2006-01-03T00:00:00Z</updated>
|
<updated planet:format='January 03, 2006 12:00 AM'>2006-01-03T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>two</planet:name>
|
<planet:name>two</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
<link href='http://example.com/4' type='text/html' rel='alternate'/>
|
||||||
<title>Mars</title>
|
<title>Mars</title>
|
||||||
<content>the Red Planet</content>
|
<content>the Red Planet</content>
|
||||||
<updated>2006-01-04T00:00:00Z</updated>
|
<updated planet:format='January 04, 2006 12:00 AM'>2006-01-04T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
<id>tag:planet.intertwingly.net,2006:testfeed2</id>
|
||||||
<author>
|
<author>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>two</planet:name>
|
<planet:name>two</planet:name>
|
||||||
</source>
|
</source>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
<link href='http://example.com/1' type='text/html' rel='alternate'/>
|
||||||
<title>Mercury</title>
|
<title>Mercury</title>
|
||||||
<summary>Messenger of the Roman Gods</summary>
|
<summary>Messenger of the Roman Gods</summary>
|
||||||
<updated>2006-01-01T00:00:00Z</updated>
|
<updated planet:format='January 01, 2006 12:00 AM'>2006-01-01T00:00:00Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
||||||
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
<link href='http://example.com/2' type='text/html' rel='alternate'/>
|
||||||
<title>Venus</title>
|
<title>Venus</title>
|
||||||
<summary>the Morning Star</summary>
|
<summary>the Morning Star</summary>
|
||||||
<updated>2006-08-18T18:30:50Z</updated>
|
<updated planet:format='August 21, 2006 12:54 PM'>2006-08-21T12:54:31Z</updated>
|
||||||
<source>
|
<source>
|
||||||
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
<link href='http://intertwingly.net/code/venus/tests/data/spider/testfeed3.rss' type='text/html' rel='alternate'/>
|
||||||
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
<link href='tests/data/spider/testfeed3.rss' type='application/atom+xml' rel='self'/>
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>one</planet:name>
|
<planet:name>one</planet:name>
|
||||||
</feed>
|
</feed>
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
<link href='http://www.intertwingly.net/blog/' type='text/html' rel='alternate'/>
|
||||||
<subtitle>It’s just data</subtitle>
|
<subtitle>It’s just data</subtitle>
|
||||||
<title>Sam Ruby</title>
|
<title>Sam Ruby</title>
|
||||||
<updated>2006-06-17T00:15:18Z</updated>
|
<updated planet:format='June 17, 2006 12:15 AM'>2006-06-17T00:15:18Z</updated>
|
||||||
<planet:name>two</planet:name>
|
<planet:name>two</planet:name>
|
||||||
</feed>
|
</feed>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
[Planet]
|
[Planet]
|
||||||
name = test planet
|
name = test planet
|
||||||
cache_directory = tests/data/splice/cache
|
cache_directory = tests/data/splice/cache
|
||||||
template_files =
|
|
||||||
|
|
||||||
[tests/data/spider/testfeed0.atom]
|
[tests/data/spider/testfeed0.atom]
|
||||||
name = not found
|
name = not found
|
||||||
|
33
tests/test_apply.py
Normal file
33
tests/test_apply.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import unittest, os, shutil
|
||||||
|
from planet import config, splice
|
||||||
|
|
||||||
|
workdir = 'tests/work/apply'
|
||||||
|
configfile = 'tests/data/apply/config.ini'
|
||||||
|
testfeed = 'tests/data/apply/feed.xml'
|
||||||
|
|
||||||
|
class ApplyTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
try:
|
||||||
|
os.makedirs(workdir)
|
||||||
|
except:
|
||||||
|
self.tearDown()
|
||||||
|
os.makedirs(workdir)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(workdir)
|
||||||
|
os.removedirs(os.path.split(workdir)[0])
|
||||||
|
|
||||||
|
def test_apply(self):
|
||||||
|
testfile = open(testfeed)
|
||||||
|
feeddata = testfile.read()
|
||||||
|
testfile.close()
|
||||||
|
|
||||||
|
config.load(configfile)
|
||||||
|
splice.apply(feeddata)
|
||||||
|
|
||||||
|
for file in ['index.html', 'default.css', 'images/foaf.png']:
|
||||||
|
path = os.path.join(workdir, file)
|
||||||
|
self.assertTrue(os.path.exists(path))
|
||||||
|
self.assertTrue(os.stat(path).st_size > 0)
|
@ -3,8 +3,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from planet import config
|
from planet import config
|
||||||
|
|
||||||
workdir = 'tests/work/spider/cache'
|
|
||||||
|
|
||||||
class ConfigTest(unittest.TestCase):
|
class ConfigTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
config.load('tests/data/config/basic.ini')
|
config.load('tests/data/config/basic.ini')
|
||||||
@ -16,7 +14,9 @@ class ConfigTest(unittest.TestCase):
|
|||||||
config.template_files())
|
config.template_files())
|
||||||
|
|
||||||
def test_feeds(self):
|
def test_feeds(self):
|
||||||
self.assertEqual(['feed1', 'feed2'], config.feeds())
|
feeds = config.feeds()
|
||||||
|
feeds.sort()
|
||||||
|
self.assertEqual(['feed1', 'feed2'], feeds)
|
||||||
|
|
||||||
# planet wide configuration
|
# planet wide configuration
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import unittest, os, glob, calendar
|
import unittest, os, glob, calendar, shutil
|
||||||
from planet.spider import filename, spiderFeed, spiderPlanet
|
from planet.spider import filename, spiderFeed, spiderPlanet
|
||||||
from planet import feedparser, config
|
from planet import feedparser, config
|
||||||
|
|
||||||
@ -17,13 +17,8 @@ class SpiderTest(unittest.TestCase):
|
|||||||
os.makedirs(workdir)
|
os.makedirs(workdir)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for file in glob.glob(workdir+"/sources/*"):
|
shutil.rmtree(workdir)
|
||||||
os.unlink(file)
|
os.removedirs(os.path.split(workdir)[0])
|
||||||
if os.path.exists(workdir+"/sources"):
|
|
||||||
os.rmdir(workdir+"/sources")
|
|
||||||
for file in glob.glob(workdir+"/*"):
|
|
||||||
os.unlink(file)
|
|
||||||
os.removedirs(workdir)
|
|
||||||
|
|
||||||
def test_filename(self):
|
def test_filename(self):
|
||||||
self.assertEqual('./example.com,index.html',
|
self.assertEqual('./example.com,index.html',
|
||||||
|
58
tests/test_themes.py
Normal file
58
tests/test_themes.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from planet import config
|
||||||
|
from os.path import split
|
||||||
|
|
||||||
|
class ConfigTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
config.load('tests/data/config/themed.ini')
|
||||||
|
|
||||||
|
# template directories
|
||||||
|
|
||||||
|
def test_template_directories(self):
|
||||||
|
self.assertEqual(['foo', 'bar', 'asf', 'common'],
|
||||||
|
[split(dir)[1] for dir in config.template_directories()])
|
||||||
|
|
||||||
|
# administrivia
|
||||||
|
|
||||||
|
def test_template(self):
|
||||||
|
self.assertTrue('index.html.xslt' in config.template_files())
|
||||||
|
|
||||||
|
def test_feeds(self):
|
||||||
|
feeds = config.feeds()
|
||||||
|
feeds.sort()
|
||||||
|
self.assertEqual(['feed1', 'feed2'], feeds)
|
||||||
|
|
||||||
|
# planet wide configuration
|
||||||
|
|
||||||
|
def test_name(self):
|
||||||
|
self.assertEqual('Test Configuration', config.name())
|
||||||
|
|
||||||
|
def test_link(self):
|
||||||
|
self.assertEqual('Unconfigured Planet', config.link())
|
||||||
|
|
||||||
|
# per template configuration
|
||||||
|
|
||||||
|
def test_days_per_page(self):
|
||||||
|
self.assertEqual(7, config.days_per_page('index.html.xslt'))
|
||||||
|
self.assertEqual(0, config.days_per_page('atom.xml.xslt'))
|
||||||
|
|
||||||
|
def test_items_per_page(self):
|
||||||
|
self.assertEqual(50, config.items_per_page('index.html.xslt'))
|
||||||
|
self.assertEqual(50, config.items_per_page('atom.xml.xslt'))
|
||||||
|
|
||||||
|
def test_encoding(self):
|
||||||
|
self.assertEqual('utf-8', config.encoding('index.html.xslt'))
|
||||||
|
self.assertEqual('utf-8', config.encoding('atom.xml.xslt'))
|
||||||
|
|
||||||
|
# dictionaries
|
||||||
|
|
||||||
|
def test_feed_options(self):
|
||||||
|
self.assertEqual('one', config.feed_options('feed1')['name'])
|
||||||
|
self.assertEqual('two', config.feed_options('feed2')['name'])
|
||||||
|
|
||||||
|
def test_template_options(self):
|
||||||
|
option = config.template_options('index.html.xslt')
|
||||||
|
self.assertEqual('7', option['days_per_page'])
|
||||||
|
self.assertEqual('50', option['items_per_page'])
|
19
themes/asf/config.ini
Normal file
19
themes/asf/config.ini
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# This template is based on the one originally developed by Stefano Mazzocci
|
||||||
|
# for planetapache.org, and modified by Sam Ruby for planet.intertwingly.net
|
||||||
|
|
||||||
|
[Planet]
|
||||||
|
template_files:
|
||||||
|
atom.xml.xslt
|
||||||
|
foafroll.xml.xslt
|
||||||
|
index.html.xslt
|
||||||
|
opml.xml.xslt
|
||||||
|
|
||||||
|
template_directories:
|
||||||
|
../common
|
||||||
|
|
||||||
|
bill_of_materials:
|
||||||
|
default.css
|
||||||
|
personalize.js
|
||||||
|
images/feed-icon-10x10.png
|
||||||
|
images/opml.png
|
||||||
|
images/foaf.png
|
429
themes/asf/default.css
Normal file
429
themes/asf/default.css
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/*
|
||||||
|
* Written by Stefano Mazzocchi <stefano at apache dot org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------------- Global Definitions -------------------- */
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
color: #222;
|
||||||
|
background-color: #fff;
|
||||||
|
quotes: "\201C" "\201E" "\2018" "\2019";
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active {
|
||||||
|
}
|
||||||
|
|
||||||
|
a:focus {
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: x-large;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.25em;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
color: #000;
|
||||||
|
font-weight: normal;
|
||||||
|
background-color: #eee;
|
||||||
|
border-bottom: 2px solid #bbb
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------- Sidebar --------------------------- */
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
float: right;
|
||||||
|
top: 150px;
|
||||||
|
right: 0px;
|
||||||
|
width: 210px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
padding: 0px 0px 20px 0px;
|
||||||
|
margin: 0px 0px 20px 20px;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar h2 {
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: x-small;
|
||||||
|
color: #666;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 2px 0px 2px 4px;
|
||||||
|
margin: 15px 0px 5px 10px;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar p {
|
||||||
|
font-size: x-small;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul {
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin-left: 5px;
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar li {
|
||||||
|
margin-left: 0px;
|
||||||
|
text-indent: -15px;
|
||||||
|
list-style-type: none;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar dl {
|
||||||
|
font-size: x-small;
|
||||||
|
padding-left: 1.0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar dl ul {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar dt {
|
||||||
|
margin-top: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-left: 1.0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar dd {
|
||||||
|
margin-left: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar .message {
|
||||||
|
cursor: help;
|
||||||
|
border-bottom: 1px dashed red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar a.message:hover {
|
||||||
|
cursor: help;
|
||||||
|
background-color: #ffD0D0;
|
||||||
|
border: 1px dashed red !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------- Body ---------------------------- */
|
||||||
|
|
||||||
|
#body {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#body h2.date {
|
||||||
|
text-transform: none;
|
||||||
|
font-size: medium;
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: right;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
background-color: #eee;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding: 1px 15px 1px 5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------- News ---------------------------- */
|
||||||
|
|
||||||
|
.news {
|
||||||
|
margin: 30px 10px 30px 10px;
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news > h3 {
|
||||||
|
text-indent: -10px;
|
||||||
|
margin: 12px;
|
||||||
|
padding: 0px;
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news > h3 > a:first-child {
|
||||||
|
margin-left: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.news > h3 > a:first-child:before {
|
||||||
|
content: '⌘';
|
||||||
|
color: #D70;
|
||||||
|
margin-left: -18px;
|
||||||
|
margin-right: 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.icon {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content {
|
||||||
|
margin: 5px 5px 5px 15px;
|
||||||
|
padding: 0px 5px 0px 5px;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
line-height: 1.2em;
|
||||||
|
font-size: small;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .links {
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .permalink {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------- News Content ---------------------------- */
|
||||||
|
|
||||||
|
.news .content p {
|
||||||
|
line-height: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content img {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content blockquote {
|
||||||
|
margin: 10px 35px 10px 35px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content pre {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: medium;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 20px 10px 20px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content ul, .news .content ol {
|
||||||
|
margin: 5px 35px 5px 35px;
|
||||||
|
padding: 5px;
|
||||||
|
counter-reset: item;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content ul > ul, .news .content ul > ol, .news .content ol > ul, .news .content ol > ol {
|
||||||
|
margin: 0px 0px 0px 35px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content li {
|
||||||
|
padding: 1px;
|
||||||
|
line-height: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news code {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: medium;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000;
|
||||||
|
border-bottom: 1px dotted #777;
|
||||||
|
margin: 0px 2px 0px 2px;
|
||||||
|
padding: 1px 1px 1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content a:hover {
|
||||||
|
border: 1px dotted #000;
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 1px 2px 1px 2px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content a:active {
|
||||||
|
background-color: #ccc !important;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
padding: 1px 2px 1px 2px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .content a:focus {
|
||||||
|
border: 1px solid #fff !important;
|
||||||
|
background-color: #ccc !important;
|
||||||
|
padding: 1px 2px 1px 2px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------- Accomodations ----------------------- */
|
||||||
|
|
||||||
|
/* boing boing */
|
||||||
|
br {
|
||||||
|
clear: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* engadget */
|
||||||
|
h6 {
|
||||||
|
clear: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cadenhead */
|
||||||
|
p.sourcecode {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: medium;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 20px 10px 20px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cadenhead */
|
||||||
|
span.sourcecode {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: medium;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: large;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hsivonen */
|
||||||
|
ul p, ol p {
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* programmableweb */
|
||||||
|
.imgRight {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gizmodo */
|
||||||
|
img.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gizmodo */
|
||||||
|
img.right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gizmodo */
|
||||||
|
img.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wikipedia */
|
||||||
|
table {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* del.icio.us */
|
||||||
|
.delicious-tags {
|
||||||
|
font-size: x-small;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* musings */
|
||||||
|
img.mathlogo, img.svglogo {
|
||||||
|
float: right;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
math {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
math[display=block] {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eqno {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sutor */
|
||||||
|
img.post-img-right {
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* niall */
|
||||||
|
img.floatright {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* jason kolb */
|
||||||
|
.FeaturedPost > li {
|
||||||
|
list-style-type: none;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GigaOM */
|
||||||
|
p img {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tantek */
|
||||||
|
ul.tags,ul.tags li,h4.tags {
|
||||||
|
display:inline;
|
||||||
|
font-size: x-small
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.tags a:link, ul.tags a:visited {
|
||||||
|
color:green
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DiveIntoMark */
|
||||||
|
.framed {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------- Footer ---------------------------- */
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 30px 0px 50px 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer p {
|
||||||
|
padding: 2px 2px 2px 5px;
|
||||||
|
background-color: #ccc;
|
||||||
|
border-top: 1px solid #aaa;
|
||||||
|
border-bottom: 1px solid #aaa;
|
||||||
|
border-left: 1px solid #aaa;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: left;
|
||||||
|
}
|
153
themes/asf/index.html.xslt
Normal file
153
themes/asf/index.html.xslt
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:planet="http://planet.intertwingly.net/"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<xsl:output indent="yes" method="html"/>
|
||||||
|
|
||||||
|
<xsl:template match="atom:feed">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
|
<title><xsl:value-of select="atom:title"/></title>
|
||||||
|
<meta name="generator" content="{atom:generator}" />
|
||||||
|
<xsl:if test="atom:link[@rel='self']">
|
||||||
|
<link rel="alternate" href="{atom:link[@rel='self']/@uri}"
|
||||||
|
title="{atom:title}" type="{atom:link[@rel='self']/@type}" />
|
||||||
|
</xsl:if>
|
||||||
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
|
<script type="text/javascript" src="personalize.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<body>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h1><xsl:value-of select="atom:title"/></h1>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<div id="sidebar">
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h2>Subscriptions</h2>
|
||||||
|
<ul>
|
||||||
|
<xsl:for-each select="planet:source">
|
||||||
|
<xsl:sort select="planet:name"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<li>
|
||||||
|
<a href="{atom:link[@rel='self']/@href}" title="subscribe">
|
||||||
|
<img src="images/feed-icon-10x10.png" alt="(feed)"/>
|
||||||
|
</a>
|
||||||
|
<a href="{atom:link[@rel='alternate']/@href}">
|
||||||
|
<xsl:value-of select="planet:name"/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h2>Info</h2>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt>Last updated:</dt>
|
||||||
|
<dd><span class="date" title="GMT"><xsl:value-of select="atom:updated"/></span></dd>
|
||||||
|
<dt>Powered by:</dt>
|
||||||
|
<dd><a href="http://intertwingly.net/code/planet/"><img src="images/planet.png" width="80" height="15" alt="Planet" border="0" /></a></dd>
|
||||||
|
<dt>Export:</dt>
|
||||||
|
<dd>
|
||||||
|
<ul>
|
||||||
|
<li><a href="opml.xml"><img src="images/opml.png" alt="OPML" /></a></li>
|
||||||
|
<li><a href="foafroll.xml"><img src="images/foaf.png" alt="FOAF" /></a></li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<xsl:apply-templates select="atom:entry"/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="atom:entry">
|
||||||
|
<!-- date header -->
|
||||||
|
<xsl:variable name="date" select="substring(atom:updated,1,10)"/>
|
||||||
|
<xsl:if test="not(preceding-sibling::atom:entry
|
||||||
|
[substring(atom:updated,1,10) = $date])">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h2 class="date"><xsl:value-of select="$date"/></h2>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<div class="news">
|
||||||
|
|
||||||
|
<xsl:if test="@xml:lang">
|
||||||
|
<xsl:attribute name="xml:lang" select="{@xml:lang}"/>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<!-- entry title -->
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h3>
|
||||||
|
<xsl:if test="atom:source/atom:icon">
|
||||||
|
<img src="{atom:source/atom:icon}" class="icon"/>
|
||||||
|
</xsl:if>
|
||||||
|
<a href="{atom:source/atom:link['alternate']/@href}" class="icon">
|
||||||
|
<xsl:attribute name="title" select="{atom:source/atom:title}"/>
|
||||||
|
<xsl:value-of select="atom:source/planet:name"/>
|
||||||
|
</a>
|
||||||
|
<xsl:if test="atom:title">
|
||||||
|
<xsl:text>—</xsl:text>
|
||||||
|
<a href="{atom:link[@rel='alternate']/@href}">
|
||||||
|
<xsl:if test="atom:title/@xml:lang != @xml:lang">
|
||||||
|
<xsl:attribute name="xml:lang" select="{atom:title/@xml:lang}"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="atom:title"/>
|
||||||
|
</a>
|
||||||
|
</xsl:if>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<!-- entry content -->
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<div class="content">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="atom:content">
|
||||||
|
<xsl:if test="atom:content/@xml:lang != @xml:lang">
|
||||||
|
<xsl:attribute name="xml:lang" select="{atom:content/@xml:lang}"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:copy-of select="atom:content/*"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:if test="atom:summary/@xml:lang != @xml:lang">
|
||||||
|
<xsl:attribute name="xml:lang" select="{atom:summary/@xml:lang}"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:copy-of select="atom:summary/*"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- entry footer -->
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<div class="permalink">
|
||||||
|
<a href="{atom:link[@rel='alternate']/@href}">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="atom:author/atom:name">
|
||||||
|
<xsl:text>by </xsl:text>
|
||||||
|
<xsl:value-of select="atom:author/atom:name"/>
|
||||||
|
<xsl:text> at </xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="atom:source/atom:author/atom:name">
|
||||||
|
<xsl:text>by </xsl:text>
|
||||||
|
<xsl:value-of select="atom:source/atom:author/atom:name"/>
|
||||||
|
<xsl:text> at </xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
<span class="date" title="GMT">
|
||||||
|
<xsl:value-of select="atom:updated"/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
220
themes/asf/personalize.js
Normal file
220
themes/asf/personalize.js
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
var entries = []; // list of news items
|
||||||
|
|
||||||
|
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
|
||||||
|
"Friday", "Saturday"];
|
||||||
|
var months = ["January", "February", "March", "April", "May", "June", "July",
|
||||||
|
"August", "September", "October", "November", "December"];
|
||||||
|
|
||||||
|
// event complete: stop propagation of the event
|
||||||
|
function stopPropagation(event) {
|
||||||
|
if (event.preventDefault) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
} else {
|
||||||
|
event.returnValue = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scroll back to the previous article
|
||||||
|
function prevArticle(event) {
|
||||||
|
for (var i=entries.length; --i>=0;) {
|
||||||
|
if (entries[i].anchor.offsetTop < document.documentElement.scrollTop) {
|
||||||
|
window.location.hash=entries[i].anchor.id;
|
||||||
|
stopPropagation(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// advance to the next article
|
||||||
|
function nextArticle(event) {
|
||||||
|
for (var i=1; i<entries.length; i++) {
|
||||||
|
if (entries[i].anchor.offsetTop-20 > document.documentElement.scrollTop) {
|
||||||
|
window.location.hash=entries[i].anchor.id;
|
||||||
|
stopPropagation(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// process keypresses
|
||||||
|
function navkey(event) {
|
||||||
|
var checkbox = document.getElementById('navkeys');
|
||||||
|
if (!checkbox || !checkbox.checked) return;
|
||||||
|
|
||||||
|
if (!event) event=window.event;
|
||||||
|
key=event.keyCode;
|
||||||
|
|
||||||
|
if (!document.documentElement) return;
|
||||||
|
if (!entries[0].anchor || !entries[0].anchor.offsetTop) return;
|
||||||
|
|
||||||
|
if (key == 'J'.charCodeAt(0)) nextArticle(event);
|
||||||
|
if (key == 'K'.charCodeAt(0)) prevArticle(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create (or reset) a cookie
|
||||||
|
function createCookie(name,value,days) {
|
||||||
|
if (days) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||||
|
var expires = "; expires="+date.toGMTString();
|
||||||
|
}
|
||||||
|
else expires = "";
|
||||||
|
document.cookie = name+"="+value+expires+"; path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
// read a cookie
|
||||||
|
function readCookie(name) {
|
||||||
|
var nameEQ = name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i=0;i < ca.length;i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// each time the value of the option changes, update the cookie
|
||||||
|
function selectOption() {
|
||||||
|
var checkbox = document.getElementById('navkeys');
|
||||||
|
if (!checkbox) return;
|
||||||
|
createCookie("navkeys", checkbox.checked?'true':'false', 365);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add navkeys option to sidebar
|
||||||
|
function addOption(event) {
|
||||||
|
if (entries.length > 1 && entries[entries.length-1].parent.offsetTop > 0) {
|
||||||
|
var sidebar = document.getElementById('sidebar');
|
||||||
|
if (!sidebar) return;
|
||||||
|
|
||||||
|
for (var i=entries.length; --i>=0;) {
|
||||||
|
var a = entries[i].anchor = document.createElement('a');
|
||||||
|
a.id = "news-" + i;
|
||||||
|
entries[i].parent.insertBefore(a, entries[i].parent.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
var h2 = document.createElement('h2');
|
||||||
|
h2.appendChild(document.createTextNode('Options'));
|
||||||
|
sidebar.appendChild(h2);
|
||||||
|
|
||||||
|
var form = document.createElement('form');
|
||||||
|
var p = document.createElement('p');
|
||||||
|
var input = document.createElement('input');
|
||||||
|
input.type = "checkbox";
|
||||||
|
input.id = "navkeys";
|
||||||
|
p.appendChild(input);
|
||||||
|
var a = document.createElement('a');
|
||||||
|
a.title = "Navigate entries";
|
||||||
|
a.appendChild(document.createTextNode('Enable '));
|
||||||
|
var code = document.createElement('code');
|
||||||
|
code.appendChild(document.createTextNode('J'));
|
||||||
|
a.appendChild(code);
|
||||||
|
a.appendChild(document.createTextNode(' and '));
|
||||||
|
code = document.createElement('code');
|
||||||
|
code.appendChild(document.createTextNode('K'));
|
||||||
|
a.appendChild(code);
|
||||||
|
a.appendChild(document.createTextNode(' keys'));
|
||||||
|
p.appendChild(a);
|
||||||
|
form.appendChild(p);
|
||||||
|
sidebar.appendChild(form);
|
||||||
|
|
||||||
|
var cookie = readCookie("navkeys");
|
||||||
|
if (cookie && cookie == 'true') input.checked = true;
|
||||||
|
input.onclick = selectOption;
|
||||||
|
document.onkeydown = navkey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert date to local time
|
||||||
|
var localere = /^(\w+) (\d+) (\w+) \d+ 0?(\d\d?:\d\d):\d\d ([AP]M) (EST|EDT|CST|CDT|MST|MDT|PST|PDT)/;
|
||||||
|
function localizeDate(element) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(Date.parse(element.innerHTML + " GMT"));
|
||||||
|
|
||||||
|
var local = date.toLocaleString();
|
||||||
|
var match = local.match(localere);
|
||||||
|
if (match) {
|
||||||
|
element.innerHTML = match[4] + ' ' + match[5].toLowerCase();
|
||||||
|
element.title = match[6] + " \u2014 " +
|
||||||
|
match[1] + ', ' + match[3] + ' ' + match[2];
|
||||||
|
return days[date.getDay()] + ', ' + months[date.getMonth()] + ' ' +
|
||||||
|
date.getDate() + ', ' + date.getFullYear();
|
||||||
|
} else {
|
||||||
|
element.title = element.innerHTML + ' GMT';
|
||||||
|
element.innerHTML = local;
|
||||||
|
return days[date.getDay()] + ', ' + date.getDate() + ' ' +
|
||||||
|
months[date.getMonth()] + ' ' + date.getFullYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// find entries (and localizeDates)
|
||||||
|
function findEntries() {
|
||||||
|
|
||||||
|
var span = document.getElementsByTagName('span');
|
||||||
|
|
||||||
|
for (var i=0; i<span.length; i++) {
|
||||||
|
if (span[i].className == "date" && span[i].title == "GMT") {
|
||||||
|
var date = localizeDate(span[i]);
|
||||||
|
|
||||||
|
var parent = span[i];
|
||||||
|
while (parent && parent.className != 'news') {
|
||||||
|
parent = parent.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
var info = entries[entries.length] = new Object();
|
||||||
|
info.parent = parent;
|
||||||
|
info.date = date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert/remove date headers to indicate change of date in local time zone
|
||||||
|
function moveDateHeaders() {
|
||||||
|
lastdate = ''
|
||||||
|
for (var i=0; i<entries.length; i++) {
|
||||||
|
var parent = entries[i].parent;
|
||||||
|
var date = entries[i].date;
|
||||||
|
|
||||||
|
sibling = parent.previousSibling;
|
||||||
|
while (sibling && sibling.nodeType != 1) {
|
||||||
|
sibling = sibling.previousSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sibling && sibling.nodeName.toLowerCase() == 'h2') {
|
||||||
|
if (lastdate == date) {
|
||||||
|
sibling.parentNode.removeChild(sibling);
|
||||||
|
} else {
|
||||||
|
sibling.innerHTML = date;
|
||||||
|
lastdate = date;
|
||||||
|
}
|
||||||
|
} else if (lastdate != date) {
|
||||||
|
var h2 = document.createElement('h2');
|
||||||
|
h2.className = 'date'
|
||||||
|
h2.appendChild(document.createTextNode(date));
|
||||||
|
parent.parentNode.insertBefore(h2, parent);
|
||||||
|
lastdate = date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust dates to local time zones, optionally provide navigation keys
|
||||||
|
function personalize() {
|
||||||
|
findEntries();
|
||||||
|
addOption();
|
||||||
|
moveDateHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
// hook event
|
||||||
|
window.onload = personalize;
|
||||||
|
if (document.addEventListener) {
|
||||||
|
onDOMLoad = function() {
|
||||||
|
window.onload = undefined;
|
||||||
|
personalize();
|
||||||
|
};
|
||||||
|
document.addEventListener("DOMContentLoaded", onDOMLoad, false);
|
||||||
|
}
|
25
themes/common/atom.xml.xslt
Normal file
25
themes/common/atom.xml.xslt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:indexing="urn:atom-extension:indexing"
|
||||||
|
xmlns:planet="http://planet.intertwingly.net/"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<!-- strip planet elements and attributes -->
|
||||||
|
<xsl:template match="planet:*"/>
|
||||||
|
|
||||||
|
<!-- add Google/LiveJournal-esque noindex directive -->
|
||||||
|
<xsl:template match="atom:feed">
|
||||||
|
<xsl:copy>
|
||||||
|
<xsl:attribute name="indexing:index">no</xsl:attribute>
|
||||||
|
<xsl:apply-templates select="@*|node()"/>
|
||||||
|
</xsl:copy>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- pass through everything else -->
|
||||||
|
<xsl:template match="@*|node()">
|
||||||
|
<xsl:copy>
|
||||||
|
<xsl:apply-templates select="@*|node()"/>
|
||||||
|
</xsl:copy>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
39
themes/common/foafroll.xml.xslt
Normal file
39
themes/common/foafroll.xml.xslt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||||
|
xmlns:foaf="http://xmlns.com/foaf/0.1/"
|
||||||
|
xmlns:rss="http://purl.org/rss/1.0/"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:planet="http://planet.intertwingly.net/"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<xsl:output indent="yes" method="xml"/>
|
||||||
|
|
||||||
|
<xsl:template match="atom:feed">
|
||||||
|
<rdf:RDF>
|
||||||
|
<foaf:Group>
|
||||||
|
<foaf:name><xsl:value-of select="atom:author/atom:name"/></foaf:name>
|
||||||
|
<foaf:homepage><xsl:value-of select="atom:author/atom:uri"/></foaf:homepage>
|
||||||
|
|
||||||
|
<xsl:apply-templates select="planet:source"/>
|
||||||
|
</foaf:Group>
|
||||||
|
</rdf:RDF>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="planet:source">
|
||||||
|
<foaf:member>
|
||||||
|
<foaf:Agent>
|
||||||
|
<foaf:name><xsl:value-of select="planet:name"/></foaf:name>
|
||||||
|
<foaf:weblog>
|
||||||
|
<foaf:Document rdf:about="{atom:link[@rel='alternate']/@href}">
|
||||||
|
<dc:title><xsl:value-of select="atom:title"/></dc:title>
|
||||||
|
<rdfs:seeAlso>
|
||||||
|
<rss:channel rdf:about="{atom:link[@rel='self']/@href}" />
|
||||||
|
</rdfs:seeAlso>
|
||||||
|
</foaf:Document>
|
||||||
|
</foaf:weblog>
|
||||||
|
</foaf:Agent>
|
||||||
|
</foaf:member>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
BIN
themes/common/images/feed-icon-10x10.png
Normal file
BIN
themes/common/images/feed-icon-10x10.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 469 B |
BIN
themes/common/images/foaf.png
Normal file
BIN
themes/common/images/foaf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
themes/common/images/opml.png
Normal file
BIN
themes/common/images/opml.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 804 B |
BIN
themes/common/images/planet.png
Normal file
BIN
themes/common/images/planet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 426 B |
25
themes/common/opml.xml.xslt
Normal file
25
themes/common/opml.xml.xslt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:planet="http://planet.intertwingly.net/"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<xsl:output indent="yes" method="xml"/>
|
||||||
|
|
||||||
|
<xsl:template match="atom:feed">
|
||||||
|
<opml version="1.1">
|
||||||
|
<head>
|
||||||
|
<title><xsl:value-of select="atom:title"/></title>
|
||||||
|
<dateModified><xsl:value-of select="atom:updated/@planet:format"/></dateModified>
|
||||||
|
<ownerName><xsl:value-of select="atom:author/atom:name"/></ownerName>
|
||||||
|
<ownerEmail><xsl:value-of select="atom:author/atom:email"/></ownerEmail>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<xsl:for-each select="planet:source">
|
||||||
|
<outline type="rss" text="{planet:name}" title="{atom:title}"
|
||||||
|
xmlUrl="{atom:link[@rel='self']/@href}"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</body>
|
||||||
|
</opml>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
Loading…
x
Reference in New Issue
Block a user