Removing old feedvalidator, unused fab commands.

This commit is contained in:
Samuel Clay 2020-06-01 10:42:05 -04:00
parent 16b86fec3a
commit eaa24a0412
2358 changed files with 0 additions and 85533 deletions

View file

@ -137,7 +137,6 @@ these after the installation below.
the `fabfile.py`. You should also have MySQL/PostgreSQL and MongoDB already installed.
fab -R local setup_python
fab -R local setup_imaging
fab -R local setup_mongoengine
fab -R local setup_forked_mongoengine
fab -R local setup_repo_local_settings

24
fabfile.py vendored
View file

@ -212,7 +212,6 @@ def setup_common():
# setup_pymongo_repo()
setup_logrotate()
setup_nginx()
# setup_imaging()
setup_munin()
def setup_all():
@ -458,25 +457,6 @@ def setup_libxml_code():
def setup_psycopg():
sudo('easy_install -U psycopg2')
# def setup_python():
# # sudo('easy_install -U $(<%s)' %
# # os.path.join(env.NEWSBLUR_PATH, 'config/requirements.txt'))
# pip()
# put('config/pystartup.py', '.pystartup')
#
# # with cd(os.path.join(env.NEWSBLUR_PATH, 'vendor/cjson')):
# # sudo('python setup.py install')
#
# with settings(warn_only=True):
# sudo('echo "import sys; sys.setdefaultencoding(\'utf-8\')" | sudo tee /usr/lib/python2.7/sitecustomize.py')
# sudo("chmod a+r /usr/local/lib/python2.7/dist-packages/httplib2-0.8-py2.7.egg/EGG-INFO/top_level.txt")
# sudo("chmod a+r /usr/local/lib/python2.7/dist-packages/python_dateutil-2.1-py2.7.egg/EGG-INFO/top_level.txt")
# sudo("chmod a+r /usr/local/lib/python2.7/dist-packages/httplib2-0.8-py2.7.egg/httplib2/cacerts.txt")
#
# if env.user == 'ubuntu':
# with settings(warn_only=True):
# sudo('chown -R ubuntu.ubuntu /home/ubuntu/.python-eggs')
def setup_virtualenv():
sudo('rm -fr ~/.cache') # Clean `sudo pip`
sudo('pip install --upgrade virtualenv')
@ -529,10 +509,6 @@ def solo_pip(role):
pip()
celery()
# PIL - Only if python-imaging didn't install through apt-get, like on Mac OS X.
def setup_imaging():
sudo('easy_install --always-unzip pil')
def setup_supervisor():
sudo('apt-get -y install supervisor')
put('config/supervisord.conf', '/etc/supervisor/supervisord.conf', use_sudo=True)

View file

@ -1,290 +0,0 @@
"""$Id: __init__.py 699 2006-09-25 02:01:18Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 699 $"
__date__ = "$Date: 2006-09-25 02:01:18 +0000 (Mon, 25 Sep 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
import socket
if hasattr(socket, 'setdefaulttimeout'):
socket.setdefaulttimeout(10)
Timeout = socket.timeout
else:
import timeoutsocket
timeoutsocket.setDefaultSocketTimeout(10)
Timeout = timeoutsocket.Timeout
import urllib2
import logging
from logging import *
from xml.sax import SAXException
from xml.sax.xmlreader import InputSource
import re
import xmlEncoding
import mediaTypes
from httplib import BadStatusLine
MAXDATALENGTH = 200000
def _validate(aString, firstOccurrenceOnly, loggedEvents, base, encoding, selfURIs=None):
"""validate RSS from string, returns validator object"""
from xml.sax import make_parser, handler
from base import SAXDispatcher
from exceptions import UnicodeError
from cStringIO import StringIO
# By now, aString should be Unicode
source = InputSource()
source.setByteStream(StringIO(xmlEncoding.asUTF8(aString)))
validator = SAXDispatcher(base, selfURIs or [base], encoding)
validator.setFirstOccurrenceOnly(firstOccurrenceOnly)
validator.loggedEvents += loggedEvents
# experimental RSS-Profile draft 1.06 support
validator.setLiterals(re.findall('&#x26;(\w+);',aString))
xmlver = re.match("^<\?\s*xml\s+version\s*=\s*['\"]([-a-zA-Z0-9_.:]*)['\"]",aString)
if xmlver and xmlver.group(1)<>'1.0':
validator.log(logging.BadXmlVersion({"version":xmlver.group(1)}))
try:
from xml.sax.expatreader import ExpatParser
class fake_dtd_parser(ExpatParser):
def reset(self):
ExpatParser.reset(self)
self._parser.UseForeignDTD(1)
parser = fake_dtd_parser()
except:
parser = make_parser()
parser.setFeature(handler.feature_namespaces, 1)
parser.setContentHandler(validator)
parser.setErrorHandler(validator)
parser.setEntityResolver(validator)
if hasattr(parser, '_ns_stack'):
# work around bug in built-in SAX parser (doesn't recognize xml: namespace)
# PyXML doesn't have this problem, and it doesn't have _ns_stack either
parser._ns_stack.append({'http://www.w3.org/XML/1998/namespace':'xml'})
def xmlvalidate(log):
import libxml2
from StringIO import StringIO
from random import random
prefix="...%s..." % str(random()).replace('0.','')
msg=[]
libxml2.registerErrorHandler(lambda msg,str: msg.append(str), msg)
input = libxml2.inputBuffer(StringIO(xmlEncoding.asUTF8(aString)))
reader = input.newTextReader(prefix)
reader.SetParserProp(libxml2.PARSER_VALIDATE, 1)
ret = reader.Read()
while ret == 1: ret = reader.Read()
msg=''.join(msg)
for line in msg.splitlines():
if line.startswith(prefix): log(line.split(':',4)[-1].strip())
validator.xmlvalidator=xmlvalidate
try:
parser.parse(source)
except SAXException:
pass
except UnicodeError:
import sys
exctype, value = sys.exc_info()[:2]
validator.log(logging.UnicodeError({"exception":value}))
if validator.getFeedType() == TYPE_RSS1:
try:
from rdflib.syntax.parsers.RDFXMLHandler import RDFXMLHandler
class Handler(RDFXMLHandler):
ns_prefix_map = {}
prefix_ns_map = {}
def add(self, triple): pass
def __init__(self, dispatcher):
RDFXMLHandler.__init__(self, self)
self.dispatcher=dispatcher
def error(self, message):
self.dispatcher.log(InvalidRDF({"message": message}))
source.getByteStream().reset()
parser.reset()
parser.setContentHandler(Handler(parser.getContentHandler()))
parser.setErrorHandler(handler.ErrorHandler())
parser.parse(source)
except:
pass
return validator
def validateStream(aFile, firstOccurrenceOnly=0, contentType=None, base=""):
loggedEvents = []
if contentType:
(mediaType, charset) = mediaTypes.checkValid(contentType, loggedEvents)
else:
(mediaType, charset) = (None, None)
rawdata = aFile.read(MAXDATALENGTH)
if aFile.read(1):
raise ValidationFailure(logging.ValidatorLimit({'limit': 'feed length > ' + str(MAXDATALENGTH) + ' bytes'}))
encoding, rawdata = xmlEncoding.decode(mediaType, charset, rawdata, loggedEvents, fallback='utf-8')
validator = _validate(rawdata, firstOccurrenceOnly, loggedEvents, base, encoding)
if mediaType and validator.feedType:
mediaTypes.checkAgainstFeedType(mediaType, validator.feedType, validator.loggedEvents)
return {"feedType":validator.feedType, "loggedEvents":validator.loggedEvents}
def validateString(aString, firstOccurrenceOnly=0, fallback=None, base=""):
loggedEvents = []
if type(aString) != unicode:
encoding, aString = xmlEncoding.decode("", None, aString, loggedEvents, fallback)
else:
encoding = "utf-8" # setting a sane (?) default
if aString is not None:
validator = _validate(aString, firstOccurrenceOnly, loggedEvents, base, encoding)
return {"feedType":validator.feedType, "loggedEvents":validator.loggedEvents}
else:
return {"loggedEvents": loggedEvents}
def validateURL(url, firstOccurrenceOnly=1, wantRawData=0):
"""validate RSS from URL, returns events list, or (events, rawdata) tuple"""
loggedEvents = []
request = urllib2.Request(url)
request.add_header("Accept-encoding", "gzip, deflate")
request.add_header("User-Agent", "FeedValidator/1.3")
usock = None
try:
try:
usock = urllib2.urlopen(request)
rawdata = usock.read(MAXDATALENGTH)
if usock.read(1):
raise ValidationFailure(logging.ValidatorLimit({'limit': 'feed length > ' + str(MAXDATALENGTH) + ' bytes'}))
# check for temporary redirects
if usock.geturl()<>request.get_full_url():
from httplib import HTTPConnection
spliturl=url.split('/',3)
if spliturl[0]=="http:":
conn=HTTPConnection(spliturl[2])
conn.request("GET",'/'+spliturl[3].split("#",1)[0])
resp=conn.getresponse()
if resp.status<>301:
loggedEvents.append(TempRedirect({}))
except BadStatusLine, status:
raise ValidationFailure(logging.HttpError({'status': status.__class__}))
except urllib2.HTTPError, status:
rawdata = status.read()
lastline = rawdata.strip().split('\n')[-1].strip()
if lastline in ['</rss>','</feed>','</rdf:RDF>']:
loggedEvents.append(logging.HttpError({'status': status}))
usock = status
else:
raise ValidationFailure(logging.HttpError({'status': status}))
except urllib2.URLError, x:
raise ValidationFailure(logging.HttpError({'status': x.reason}))
except Timeout, x:
raise ValidationFailure(logging.IOError({"message": 'Server timed out', "exception":x}))
if usock.headers.get('content-encoding', None) == None:
loggedEvents.append(Uncompressed({}))
if usock.headers.get('content-encoding', None) == 'gzip':
import gzip, StringIO
try:
rawdata = gzip.GzipFile(fileobj=StringIO.StringIO(rawdata)).read()
except:
import sys
exctype, value = sys.exc_info()[:2]
event=logging.IOError({"message": 'Server response declares Content-Encoding: gzip', "exception":value})
raise ValidationFailure(event)
if usock.headers.get('content-encoding', None) == 'deflate':
import zlib
try:
rawdata = zlib.decompress(rawdata, -zlib.MAX_WBITS)
except:
import sys
exctype, value = sys.exc_info()[:2]
event=logging.IOError({"message": 'Server response declares Content-Encoding: deflate', "exception":value})
raise ValidationFailure(event)
mediaType = None
charset = None
# Is the Content-Type correct?
contentType = usock.headers.get('content-type', None)
if contentType:
(mediaType, charset) = mediaTypes.checkValid(contentType, loggedEvents)
# Check for malformed HTTP headers
for (h, v) in usock.headers.items():
if (h.find(' ') >= 0):
loggedEvents.append(HttpProtocolError({'header': h}))
selfURIs = [request.get_full_url()]
baseURI = usock.geturl()
if not baseURI in selfURIs: selfURIs.append(baseURI)
# Get baseURI from content-location and/or redirect information
if usock.headers.get('content-location', None):
from urlparse import urljoin
baseURI=urljoin(baseURI,usock.headers.get('content-location', ""))
elif usock.headers.get('location', None):
from urlparse import urljoin
baseURI=urljoin(baseURI,usock.headers.get('location', ""))
if not baseURI in selfURIs: selfURIs.append(baseURI)
usock.close()
usock = None
mediaTypes.contentSniffing(mediaType, rawdata, loggedEvents)
encoding, rawdata = xmlEncoding.decode(mediaType, charset, rawdata, loggedEvents, fallback='utf-8')
if rawdata is None:
return {'loggedEvents': loggedEvents}
rawdata = rawdata.replace('\r\n', '\n').replace('\r', '\n') # normalize EOL
validator = _validate(rawdata, firstOccurrenceOnly, loggedEvents, baseURI, encoding, selfURIs)
# Warn about mismatches between media type and feed version
if mediaType and validator.feedType:
mediaTypes.checkAgainstFeedType(mediaType, validator.feedType, validator.loggedEvents)
params = {"feedType":validator.feedType, "loggedEvents":validator.loggedEvents}
if wantRawData:
params['rawdata'] = rawdata
return params
finally:
try:
if usock: usock.close()
except:
pass
__all__ = ['base',
'channel',
'compatibility',
'image',
'item',
'logging',
'rdf',
'root',
'rss',
'skipHours',
'textInput',
'util',
'validators',
'validateURL',
'validateString']

View file

@ -1,53 +0,0 @@
"""$Id: author.py 699 2006-09-25 02:01:18Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 699 $"
__date__ = "$Date: 2006-09-25 02:01:18 +0000 (Mon, 25 Sep 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from base import validatorBase
from validators import *
#
# author element.
#
class author(validatorBase):
def getExpectedAttrNames(self):
return [(u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', u'parseType')]
def validate(self):
if not "name" in self.children and not "atom_name" in self.children:
self.log(MissingElement({"parent":self.name, "element":"name"}))
def do_name(self):
return nonhtml(), nonemail(), nonblank(), noduplicates()
def do_email(self):
return addr_spec(), noduplicates()
def do_uri(self):
return nonblank(), rfc3987(), nows(), noduplicates()
def do_foaf_workplaceHomepage(self):
return rdfResourceURI()
def do_foaf_homepage(self):
return rdfResourceURI()
def do_foaf_weblog(self):
return rdfResourceURI()
def do_foaf_plan(self):
return text()
def do_foaf_firstName(self):
return text()
def do_xhtml_div(self):
from content import diveater
return diveater()
# RSS/Atom support
do_atom_name = do_name
do_atom_email = do_email
do_atom_uri = do_uri

View file

@ -1,511 +0,0 @@
"""$Id: base.py 744 2007-03-24 11:57:16Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 744 $"
__date__ = "$Date: 2007-03-24 11:57:16 +0000 (Sat, 24 Mar 2007) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from xml.sax.handler import ContentHandler
from xml.sax.xmlreader import Locator
from logging import NonCanonicalURI, NotUTF8
import re
# references:
# http://web.resource.org/rss/1.0/modules/standard.html
# http://web.resource.org/rss/1.0/modules/proposed.html
# http://dmoz.org/Reference/Libraries/Library_and_Information_Science/Technical_Services/Cataloguing/Metadata/RDF/Applications/RSS/Specifications/RSS1.0_Modules/
namespaces = {
"http://www.bloglines.com/about/specs/fac-1.0": "access",
"http://webns.net/mvcb/": "admin",
"http://purl.org/rss/1.0/modules/aggregation/": "ag",
"http://purl.org/rss/1.0/modules/annotate/": "annotate",
"http://media.tangent.org/rss/1.0/": "audio",
"http://backend.userland.com/blogChannelModule": "blogChannel",
"http://web.resource.org/cc/": "cc",
"http://www.microsoft.com/schemas/rss/core/2005": "cf",
"http://backend.userland.com/creativeCommonsRssModule": "creativeCommons",
"http://purl.org/rss/1.0/modules/company": "company",
"http://purl.org/rss/1.0/modules/content/": "content",
"http://my.theinfo.org/changed/1.0/rss/": "cp",
"http://purl.org/dc/elements/1.1/": "dc",
"http://purl.org/dc/terms/": "dcterms",
"http://purl.org/rss/1.0/modules/email/": "email",
"http://purl.org/rss/1.0/modules/event/": "ev",
"http://www.w3.org/2003/01/geo/wgs84_pos#": "geo",
"http://geourl.org/rss/module/": "geourl",
"http://www.georss.org/georss": "georss",
"http://www.opengis.net/gml": "gml",
"http://postneo.com/icbm": "icbm",
"http://purl.org/rss/1.0/modules/image/": "image",
"http://www.itunes.com/dtds/podcast-1.0.dtd": "itunes",
"http://xmlns.com/foaf/0.1/": "foaf",
"http://purl.org/rss/1.0/modules/link/": "l",
"http://search.yahoo.com/mrss/": "media",
"http://a9.com/-/spec/opensearch/1.1/": "opensearch",
"http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
"http://www.w3.org/2000/01/rdf-schema#": "rdfs",
"http://purl.org/rss/1.0/modules/reference/": "ref",
"http://purl.org/rss/1.0/modules/richequiv/": "reqv",
"http://purl.org/rss/1.0/modules/rss091#": "rss091",
"http://purl.org/rss/1.0/modules/search/": "search",
"http://purl.org/rss/1.0/modules/slash/": "slash",
"http://purl.org/rss/1.0/modules/servicestatus/": "ss",
"http://hacks.benhammersley.com/rss/streaming/": "str",
"http://purl.org/rss/1.0/modules/subscription/": "sub",
"http://purl.org/rss/1.0/modules/syndication/": "sy",
"http://purl.org/rss/1.0/modules/taxonomy/": "taxo",
"http://purl.org/rss/1.0/modules/threading/": "thr",
"http://purl.org/syndication/thread/1.0": "thr",
"http://madskills.com/public/xml/rss/module/trackback/": "trackback",
"http://wellformedweb.org/CommentAPI/": "wfw",
"http://purl.org/rss/1.0/modules/wiki/": "wiki",
"http://www.usemod.com/cgi-bin/mb.pl?ModWiki": "wiki",
"http://schemas.xmlsoap.org/soap/envelope/": "soap",
"http://www.w3.org/2005/Atom": "atom",
"http://www.w3.org/1999/xhtml": "xhtml",
"http://my.netscape.com/rdf/simple/0.9/": "rss090",
"http://purl.org/net/rss1.1#": "rss11",
"http://base.google.com/ns/1.0": "g",
"http://www.w3.org/XML/1998/namespace": "xml",
"http://openid.net/xmlns/1.0": "openid",
"xri://$xrd*($v*2.0)": "xrd",
"xri://$xrds": "xrds",
}
def near_miss(ns):
try:
return re.match(".*\w", ns).group().lower()
except:
return ns
nearly_namespaces = dict([(near_miss(u),p) for u,p in namespaces.items()])
stdattrs = [(u'http://www.w3.org/XML/1998/namespace', u'base'),
(u'http://www.w3.org/XML/1998/namespace', u'lang'),
(u'http://www.w3.org/XML/1998/namespace', u'space')]
#
# From the SAX parser's point of view, this class is the one responsible for
# handling SAX events. In actuality, all this class does is maintain a
# pushdown stack of the *real* content handlers, and delegates sax events
# to the current one.
#
class SAXDispatcher(ContentHandler):
firstOccurrenceOnly = 0
def __init__(self, base, selfURIs, encoding):
from root import root
ContentHandler.__init__(self)
self.lastKnownLine = 1
self.lastKnownColumn = 0
self.loggedEvents = []
self.feedType = 0
try:
self.xmlBase = base.encode('idna')
except:
self.xmlBase = base
self.selfURIs = selfURIs
self.encoding = encoding
self.handler_stack=[[root(self, base)]]
self.literal_entities=[]
self.defaultNamespaces = []
# experimental RSS-Profile draft 1.06 support
def setLiterals(self, literals):
for literal in literals:
if literal not in self.literal_entities:
self.literal_entities.append(literal)
def setDocumentLocator(self, locator):
self.locator = locator
ContentHandler.setDocumentLocator(self, self.locator)
def setFirstOccurrenceOnly(self, firstOccurrenceOnly=1):
self.firstOccurrenceOnly = firstOccurrenceOnly
def startPrefixMapping(self, prefix, uri):
for handler in iter(self.handler_stack[-1]):
handler.namespace[prefix] = uri
if uri and len(uri.split())>1:
from xml.sax import SAXException
self.error(SAXException('Invalid Namespace: %s' % uri))
if prefix in namespaces.values():
if not namespaces.get(uri,'') == prefix and prefix:
from logging import ReservedPrefix
preferredURI = [key for key, value in namespaces.items() if value == prefix][0]
self.log(ReservedPrefix({'prefix':prefix, 'ns':preferredURI}))
elif prefix=='wiki' and uri.find('usemod')>=0:
from logging import ObsoleteWikiNamespace
self.log(ObsoleteWikiNamespace({'preferred':namespaces[uri], 'ns':uri}))
elif namespaces.has_key(uri):
if not namespaces[uri] == prefix and prefix:
from logging import NonstdPrefix
self.log(NonstdPrefix({'preferred':namespaces[uri], 'ns':uri}))
def namespaceFor(self, prefix):
return None
def startElementNS(self, name, qname, attrs):
self.lastKnownLine = self.locator.getLineNumber()
self.lastKnownColumn = self.locator.getColumnNumber()
qname, name = name
for handler in iter(self.handler_stack[-1]):
handler.startElementNS(name, qname, attrs)
if len(attrs):
present = attrs.getNames()
unexpected = filter(lambda x: x not in stdattrs, present)
for handler in iter(self.handler_stack[-1]):
ean = handler.getExpectedAttrNames()
if ean: unexpected = filter(lambda x: x not in ean, unexpected)
for u in unexpected:
if u[0] and near_miss(u[0]) not in nearly_namespaces:
feedtype=self.getFeedType()
if (not qname) and feedtype and (feedtype==TYPE_RSS2):
from logging import InvalidExtensionAttr
self.log(InvalidExtensionAttr({"attribute":u, "element":name}))
continue
from logging import UnexpectedAttribute
if not u[0]: u=u[1]
self.log(UnexpectedAttribute({"parent":name, "attribute":u, "element":name}))
def resolveEntity(self, publicId, systemId):
if not publicId and not systemId:
import cStringIO
return cStringIO.StringIO()
try:
def log(exception):
from logging import SAXError
self.log(SAXError({'exception':str(exception)}))
if self.xmlvalidator:
self.xmlvalidator(log)
self.xmlvalidator=0
except:
pass
if (publicId=='-//Netscape Communications//DTD RSS 0.91//EN' and
systemId=='http://my.netscape.com/publish/formats/rss-0.91.dtd'):
from logging import ValidDoctype, DeprecatedDTD
self.log(ValidDoctype({}))
self.log(DeprecatedDTD({}))
else:
from logging import ContainsSystemEntity
self.lastKnownLine = self.locator.getLineNumber()
self.lastKnownColumn = self.locator.getColumnNumber()
self.log(ContainsSystemEntity({}))
from StringIO import StringIO
return StringIO()
def skippedEntity(self, name):
from logging import ValidDoctype
if [e for e in self.loggedEvents if e.__class__ == ValidDoctype]:
from htmlentitydefs import name2codepoint
if name in name2codepoint: return
from logging import UndefinedNamedEntity
self.log(UndefinedNamedEntity({'value':name}))
def characters(self, string):
self.lastKnownLine = self.locator.getLineNumber()
self.lastKnownColumn = self.locator.getColumnNumber()
for handler in iter(self.handler_stack[-1]):
handler.characters(string)
def endElementNS(self, name, qname):
self.lastKnownLine = self.locator.getLineNumber()
self.lastKnownColumn = self.locator.getColumnNumber()
qname, name = name
for handler in iter(self.handler_stack[-1]):
handler.endElementNS(name, qname)
del self.handler_stack[-1]
def push(self, handlers, name, attrs, parent):
if hasattr(handlers,'__iter__'):
for handler in iter(handlers):
handler.setElement(name, attrs, parent)
handler.value=""
handler.prevalidate()
else:
handlers.setElement(name, attrs, parent)
handlers.value=""
handlers.prevalidate()
handlers = [handlers]
self.handler_stack.append(handlers)
def log(self, event, offset=(0,0)):
def findDuplicate(self, event):
duplicates = [e for e in self.loggedEvents if e.__class__ == event.__class__]
if duplicates and (event.__class__ in [NonCanonicalURI]):
return duplicates[0]
for dup in duplicates:
for k, v in event.params.items():
if k != 'value':
if not k in dup.params or dup.params[k] != v: break
else:
return dup
if event.params.has_key('element') and event.params['element']:
if not isinstance(event.params['element'],tuple):
event.params['element']=':'.join(event.params['element'].split('_', 1))
elif event.params['element'][0]==u'http://www.w3.org/XML/1998/namespace':
event.params['element'] = 'xml:' + event.params['element'][-1]
if self.firstOccurrenceOnly:
dup = findDuplicate(self, event)
if dup:
dup.params['msgcount'] = dup.params['msgcount'] + 1
return
event.params['msgcount'] = 1
try:
line = self.locator.getLineNumber() + offset[0]
backupline = self.lastKnownLine
column = (self.locator.getColumnNumber() or 0) + offset[1]
backupcolumn = self.lastKnownColumn
except AttributeError:
line = backupline = column = backupcolumn = 1
event.params['line'] = line
event.params['backupline'] = backupline
event.params['column'] = column
event.params['backupcolumn'] = backupcolumn
self.loggedEvents.append(event)
def error(self, exception):
from logging import SAXError
self.log(SAXError({'exception':str(exception)}))
raise exception
fatalError=error
warning=error
def getFeedType(self):
return self.feedType
def setFeedType(self, feedType):
self.feedType = feedType
#
# This base class for content handlers keeps track of such administrative
# details as the parent of the current element, and delegating both log
# and push events back up the stack. It will also concatenate up all of
# the SAX events associated with character data into a value, handing such
# things as CDATA and entities.
#
# Subclasses are expected to declare "do_name" methods for every
# element that they support. These methods are expected to return the
# appropriate handler for the element.
#
# The name of the element and the names of the children processed so
# far are also maintained.
#
# Hooks are also provided for subclasses to do "prevalidation" and
# "validation".
#
from logging import TYPE_RSS2
class validatorBase(ContentHandler):
def __init__(self):
ContentHandler.__init__(self)
self.value = ""
self.attrs = None
self.children = []
self.isValid = 1
self.name = None
self.itunes = False
self.namespace = {}
def setElement(self, name, attrs, parent):
self.name = name
self.attrs = attrs
self.parent = parent
self.dispatcher = parent.dispatcher
self.line = self.dispatcher.locator.getLineNumber()
self.col = self.dispatcher.locator.getColumnNumber()
self.xmlLang = parent.xmlLang
if attrs and attrs.has_key((u'http://www.w3.org/XML/1998/namespace', u'base')):
self.xmlBase=attrs.getValue((u'http://www.w3.org/XML/1998/namespace', u'base'))
from validators import rfc3987
self.validate_attribute((u'http://www.w3.org/XML/1998/namespace',u'base'),
rfc3987)
from urlparse import urljoin
self.xmlBase = urljoin(parent.xmlBase, self.xmlBase)
else:
self.xmlBase = parent.xmlBase
return self
def simplename(self, name):
if not name[0]: return name[1]
return namespaces.get(name[0], name[0]) + ":" + name[1]
def namespaceFor(self, prefix):
if self.namespace.has_key(prefix):
return self.namespace[prefix]
elif self.parent:
return self.parent.namespaceFor(prefix)
else:
return None
def validate_attribute(self, name, rule):
if not isinstance(rule,validatorBase): rule = rule()
if isinstance(name,str): name = (None,name)
rule.setElement(self.simplename(name), {}, self)
rule.value=self.attrs.getValue(name)
rule.validate()
def validate_required_attribute(self, name, rule):
if self.attrs and self.attrs.has_key(name):
self.validate_attribute(name, rule)
else:
from logging import MissingAttribute
self.log(MissingAttribute({"attr": self.simplename(name)}))
def validate_optional_attribute(self, name, rule):
if self.attrs and self.attrs.has_key(name):
self.validate_attribute(name, rule)
def getExpectedAttrNames(self):
None
def unknown_starttag(self, name, qname, attrs):
from validators import any
return any(self, name, qname, attrs)
def startElementNS(self, name, qname, attrs):
if attrs.has_key((u'http://www.w3.org/XML/1998/namespace', u'lang')):
self.xmlLang=attrs.getValue((u'http://www.w3.org/XML/1998/namespace', u'lang'))
if self.xmlLang:
from validators import iso639_validate
iso639_validate(self.log, self.xmlLang, "xml:lang", name)
from validators import eater
feedtype=self.getFeedType()
if (not qname) and feedtype and (feedtype!=TYPE_RSS2):
from logging import UndeterminableVocabulary
self.log(UndeterminableVocabulary({"parent":self.name, "element":name, "namespace":'""'}))
qname="null"
if qname in self.dispatcher.defaultNamespaces: qname=None
nm_qname = near_miss(qname)
if nearly_namespaces.has_key(nm_qname):
prefix = nearly_namespaces[nm_qname]
qname, name = None, prefix + "_" + name
if prefix == 'itunes' and not self.itunes and not self.parent.itunes:
if hasattr(self, 'setItunes'): self.setItunes(True)
# ensure all attribute namespaces are properly defined
for (namespace,attr) in attrs.keys():
if ':' in attr and not namespace:
from logging import MissingNamespace
self.log(MissingNamespace({"parent":self.name, "element":attr}))
if qname=='http://purl.org/atom/ns#':
from logging import ObsoleteNamespace
self.log(ObsoleteNamespace({"element":"feed"}))
for key, string in attrs.items():
for c in string:
if 0x80 <= ord(c) <= 0x9F or c == u'\ufffd':
from validators import BadCharacters
self.log(BadCharacters({"parent":name, "element":key[-1]}))
if qname:
handler = self.unknown_starttag(name, qname, attrs)
name="unknown_"+name
else:
try:
self.child=name
if name.startswith('dc_'):
# handle "Qualified" Dublin Core
handler = getattr(self, "do_" + name.replace("-","_").split('.')[0])()
else:
handler = getattr(self, "do_" + name.replace("-","_"))()
except AttributeError:
if name.find(':') != -1:
from logging import MissingNamespace
self.log(MissingNamespace({"parent":self.name, "element":name}))
handler = eater()
elif name.startswith('xhtml_'):
from logging import MisplacedXHTMLContent
self.log(MisplacedXHTMLContent({"parent": ':'.join(self.name.split("_",1)), "element":name}))
handler = eater()
else:
from logging import UndefinedElement
self.log(UndefinedElement({"parent": ':'.join(self.name.split("_",1)), "element":name}))
handler = eater()
self.push(handler, name, attrs)
# MAP - always append name, even if already exists (we need this to
# check for too many hour elements in skipHours, and it doesn't
# hurt anything else)
self.children.append(name)
def normalizeWhitespace(self):
self.value = self.value.strip()
def endElementNS(self, name, qname):
self.normalizeWhitespace()
self.validate()
if self.isValid and self.name:
from validators import ValidElement
self.log(ValidElement({"parent":self.parent.name, "element":name}))
def textOK(self):
from validators import UnexpectedText
self.log(UnexpectedText({"element":self.name,"parent":self.parent.name}))
def characters(self, string):
if string.strip(): self.textOK()
line=column=0
pc=' '
for c in string:
# latin characters double encoded as utf-8
if 0x80 <= ord(c) <= 0xBF:
if 0xC2 <= ord(pc) <= 0xC3:
try:
string.encode('iso-8859-1').decode('utf-8')
from validators import BadCharacters
self.log(BadCharacters({"parent":self.parent.name, "element":self.name}), offset=(line,max(1,column-1)))
except:
pass
pc = c
# win1252
if 0x80 <= ord(c) <= 0x9F or c == u'\ufffd':
from validators import BadCharacters
self.log(BadCharacters({"parent":self.parent.name, "element":self.name}), offset=(line,column))
column=column+1
if ord(c) in (10,13):
column=0
line=line+1
self.value = self.value + string
def log(self, event, offset=(0,0)):
if not event.params.has_key('element'):
event.params['element'] = self.name
self.dispatcher.log(event, offset)
self.isValid = 0
def setFeedType(self, feedType):
self.dispatcher.setFeedType(feedType)
def getFeedType(self):
return self.dispatcher.getFeedType()
def push(self, handler, name, value):
self.dispatcher.push(handler, name, value, self)
def leaf(self):
from validators import text
return text()
def prevalidate(self):
pass
def validate(self):
pass

View file

@ -1,30 +0,0 @@
"""$Id: category.py 699 2006-09-25 02:01:18Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 699 $"
__date__ = "$Date: 2006-09-25 02:01:18 +0000 (Mon, 25 Sep 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from base import validatorBase
from validators import *
#
# author element.
#
class category(validatorBase, rfc3987_full, nonhtml):
def getExpectedAttrNames(self):
return [(None,u'term'),(None,u'scheme'),(None,u'label')]
def prevalidate(self):
self.children.append(True) # force warnings about "mixed" content
if not self.attrs.has_key((None,"term")):
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"term"}))
if self.attrs.has_key((None,"scheme")):
self.value=self.attrs.getValue((None,"scheme"))
rfc3987_full.validate(self, extraParams={"element": "scheme"})
if self.attrs.has_key((None,"label")):
self.value=self.attrs.getValue((None,"label"))
nonhtml.validate(self)

View file

@ -1,20 +0,0 @@
# http://msdn.microsoft.com/XML/rss/sle/default.aspx
from base import validatorBase
from validators import eater, text
class sort(validatorBase):
def getExpectedAttrNames(self):
return [(None,u'data-type'),(None,u'default'),(None,u'element'),(None, u'label'),(None,u'ns')]
class group(validatorBase):
def getExpectedAttrNames(self):
return [(None,u'element'),(None, u'label'),(None,u'ns')]
class listinfo(validatorBase):
def do_cf_sort(self):
return sort()
def do_cf_group(self):
return group()
class treatAs(text): pass

View file

@ -1,279 +0,0 @@
"""$Id: channel.py 711 2006-10-25 00:43:41Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 711 $"
__date__ = "$Date: 2006-10-25 00:43:41 +0000 (Wed, 25 Oct 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from base import validatorBase
from logging import *
from validators import *
from itunes import itunes_channel
from extension import *
#
# channel element.
#
class channel(validatorBase, rfc2396, extension_channel, itunes_channel):
def __init__(self):
self.link=None
validatorBase.__init__(self)
def validate(self):
if not "description" in self.children:
self.log(MissingDescription({"parent":self.name,"element":"description"}))
if not "link" in self.children:
self.log(MissingLink({"parent":self.name, "element":"link"}))
if not "title" in self.children:
self.log(MissingTitle({"parent":self.name, "element":"title"}))
if not "dc_language" in self.children and not "language" in self.children:
if not self.xmlLang:
self.log(MissingDCLanguage({"parent":self.name, "element":"language"}))
if self.children.count("image") > 1:
self.log(DuplicateElement({"parent":self.name, "element":"image"}))
if self.children.count("textInput") > 1:
self.log(DuplicateElement({"parent":self.name, "element":"textInput"}))
if self.children.count("skipHours") > 1:
self.log(DuplicateElement({"parent":self.name, "element":"skipHours"}))
if self.children.count("skipDays") > 1:
self.log(DuplicateElement({"parent":self.name, "element":"skipDays"}))
if self.attrs.has_key((rdfNS,"about")):
self.value = self.attrs.getValue((rdfNS, "about"))
rfc2396.validate(self, extraParams={"attr": "rdf:about"})
if not "items" in self.children:
self.log(MissingElement({"parent":self.name, "element":"items"}))
if self.itunes: itunes_channel.validate(self)
def do_image(self):
from image import image
return image(), noduplicates()
def do_textInput(self):
from textInput import textInput
return textInput(), noduplicates()
def do_textinput(self):
if not self.attrs.has_key((rdfNS,"about")):
# optimize for RSS 2.0. If it is not valid RDF, assume that it is
# a simple misspelling (in other words, the error message will be
# less than helpful on RSS 1.0 feeds.
self.log(UndefinedElement({"parent":self.name, "element":"textinput"}))
return eater(), noduplicates()
def do_link(self):
return link(), noduplicates()
def do_title(self):
return nonhtml(), noduplicates(), nonblank()
def do_description(self):
return nonhtml(), noduplicates()
def do_blink(self):
return blink(), noduplicates()
def do_atom_author(self):
from author import author
return author()
def do_atom_category(self):
from category import category
return category()
def do_atom_contributor(self):
from author import author
return author()
def do_atom_generator(self):
from generator import generator
return generator(), nonblank(), noduplicates()
def do_atom_id(self):
return rfc2396_full(), noduplicates()
def do_atom_icon(self):
return nonblank(), rfc2396(), noduplicates()
def do_atom_link(self):
from link import link
return link()
def do_atom_logo(self):
return nonblank(), rfc2396(), noduplicates()
def do_atom_title(self):
from content import textConstruct
return textConstruct(), noduplicates()
def do_atom_subtitle(self):
from content import textConstruct
return textConstruct(), noduplicates()
def do_atom_rights(self):
from content import textConstruct
return textConstruct(), noduplicates()
def do_atom_updated(self):
return rfc3339(), noduplicates()
def do_dc_creator(self):
if "managingEditor" in self.children:
self.log(DuplicateSemantics({"core":"managingEditor", "ext":"dc:creator"}))
return text() # duplicates allowed
def do_dc_subject(self):
if "category" in self.children:
self.log(DuplicateSemantics({"core":"category", "ext":"dc:subject"}))
return text() # duplicates allowed
def do_dc_date(self):
if "pubDate" in self.children:
self.log(DuplicateSemantics({"core":"pubDate", "ext":"dc:date"}))
return w3cdtf(), noduplicates()
def do_cc_license(self):
if "creativeCommons_license" in self.children:
self.log(DuplicateSemantics({"core":"creativeCommons:license", "ext":"cc:license"}))
return eater()
def do_creativeCommons_license(self):
if "cc_license" in self.children:
self.log(DuplicateSemantics({"core":"creativeCommons:license", "ext":"cc:license"}))
return rfc2396_full()
class rss20Channel(channel):
def do_item(self):
from item import rss20Item
return rss20Item()
def do_category(self):
return category()
def do_cloud(self):
return cloud(), noduplicates()
do_rating = validatorBase.leaf # TODO test cases?!?
def do_ttl(self):
return positiveInteger(), nonblank(), noduplicates()
def do_docs(self):
return rfc2396_full(), noduplicates()
def do_generator(self):
if "admin_generatorAgent" in self.children:
self.log(DuplicateSemantics({"core":"generator", "ext":"admin:generatorAgent"}))
return text(), noduplicates()
def do_pubDate(self):
if "dc_date" in self.children:
self.log(DuplicateSemantics({"core":"pubDate", "ext":"dc:date"}))
return rfc822(), noduplicates()
def do_managingEditor(self):
if "dc_creator" in self.children:
self.log(DuplicateSemantics({"core":"managingEditor", "ext":"dc:creator"}))
return email(), noduplicates()
def do_webMaster(self):
if "dc_publisher" in self.children:
self.log(DuplicateSemantics({"core":"webMaster", "ext":"dc:publisher"}))
return email(), noduplicates()
def do_language(self):
if "dc_language" in self.children:
self.log(DuplicateSemantics({"core":"language", "ext":"dc:language"}))
return iso639(), noduplicates()
def do_copyright(self):
if "dc_rights" in self.children:
self.log(DuplicateSemantics({"core":"copyright", "ext":"dc:rights"}))
return nonhtml(), noduplicates()
def do_lastBuildDate(self):
if "dcterms_modified" in self.children:
self.log(DuplicateSemantics({"core":"lastBuildDate", "ext":"dcterms:modified"}))
return rfc822(), noduplicates()
def do_skipHours(self):
from skipHours import skipHours
return skipHours()
def do_skipDays(self):
from skipDays import skipDays
return skipDays()
class rss10Channel(channel):
def getExpectedAttrNames(self):
return [(u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', u'about'),
(u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', u'about')]
def prevalidate(self):
if self.attrs.has_key((rdfNS,"about")):
if not "abouts" in self.dispatcher.__dict__:
self.dispatcher.__dict__["abouts"] = []
self.dispatcher.__dict__["abouts"].append(self.attrs[(rdfNS,"about")])
def do_items(self): # this actually should be from the rss1.0 ns
if not self.attrs.has_key((rdfNS,"about")):
self.log(MissingAttribute({"parent":self.name, "element":self.name, "attr":"rdf:about"}))
from item import items
return items(), noduplicates()
def do_rdfs_label(self):
return text()
def do_rdfs_comment(self):
return text()
class link(rfc2396_full):
def validate(self):
self.parent.link = self.value
rfc2396_full.validate(self)
class blink(text):
def validate(self):
self.log(NoBlink({}))
class category(nonhtml):
def getExpectedAttrNames(self):
return [(None, u'domain')]
class cloud(validatorBase):
def getExpectedAttrNames(self):
return [(None, u'domain'), (None, u'path'), (None, u'registerProcedure'),
(None, u'protocol'), (None, u'port')]
def prevalidate(self):
if (None, 'domain') not in self.attrs.getNames():
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"domain"}))
else:
self.log(ValidCloud({"parent":self.parent.name, "element":self.name, "attr":"domain"}))
try:
if int(self.attrs.getValue((None, 'port'))) <= 0:
self.log(InvalidIntegerAttribute({"parent":self.parent.name, "element":self.name, "attr":'port'}))
else:
self.log(ValidCloud({"parent":self.parent.name, "element":self.name, "attr":'port'}))
except KeyError:
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":'port'}))
except ValueError:
self.log(InvalidIntegerAttribute({"parent":self.parent.name, "element":self.name, "attr":'port'}))
if (None, 'path') not in self.attrs.getNames():
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"path"}))
else:
self.log(ValidCloud({"parent":self.parent.name, "element":self.name, "attr":"path"}))
if (None, 'registerProcedure') not in self.attrs.getNames():
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"registerProcedure"}))
else:
self.log(ValidCloud({"parent":self.parent.name, "element":self.name, "attr":"registerProcedure"}))
if (None, 'protocol') not in self.attrs.getNames():
self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"protocol"}))
else:
self.log(ValidCloud({"parent":self.parent.name, "element":self.name, "attr":"protocol"}))
## TODO - is there a list of accepted protocols for this thing?
return validatorBase.prevalidate(self)

View file

@ -1,37 +0,0 @@
"""$Id: compatibility.py 699 2006-09-25 02:01:18Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 699 $"
__date__ = "$Date: 2006-09-25 02:01:18 +0000 (Mon, 25 Sep 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from logging import *
def _must(event):
return isinstance(event, Error)
def _should(event):
return isinstance(event, Warning)
def _may(event):
return isinstance(event, Info)
def A(events):
return [event for event in events if _must(event)]
def AA(events):
return [event for event in events if _must(event) or _should(event)]
def AAA(events):
return [event for event in events if _must(event) or _should(event) or _may(event)]
def AAAA(events):
return events
def analyze(events, rawdata):
for event in events:
if isinstance(event,UndefinedElement):
if event.params['parent'] == 'root':
if event.params['element'].lower() in ['html','xhtml:html']:
return "html"
return None

View file

@ -1,151 +0,0 @@
"""$Id: content.py 699 2006-09-25 02:01:18Z rubys $"""
__author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
__version__ = "$Revision: 699 $"
__date__ = "$Date: 2006-09-25 02:01:18 +0000 (Mon, 25 Sep 2006) $"
__copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
from base import validatorBase
from validators import *
from logging import *
#
# item element.
#
class textConstruct(validatorBase,rfc2396,nonhtml):
from validators import mime_re
import re
def getExpectedAttrNames(self):
return [(None, u'type'),(None, u'src')]
def normalizeWhitespace(self):
pass
def maptype(self):
if self.type.find('/') > -1:
self.log(InvalidTextType({"parent":self.parent.name, "element":self.name, "attr":"type", "value":self.type}))
def prevalidate(self):
if self.attrs.has_key((None,"src")):
self.type=''
else:
self.type='text'
if self.getFeedType() == TYPE_RSS2 and self.name != 'atom_summary':
self.log(DuplicateDescriptionSemantics({"element":self.name}))
if self.attrs.has_key((None,"type")):
self.type=self.attrs.getValue((None,"type"))
if not self.type:
self.log(AttrNotBlank({"parent":self.parent.name, "element":self.name, "attr":"type"}))
self.maptype()
if self.attrs.has_key((None,"src")):
self.children.append(True) # force warnings about "mixed" content
self.value=self.attrs.getValue((None,"src"))
rfc2396.validate(self, errorClass=InvalidURIAttribute, extraParams={"attr": "src"})
self.value=""
if not self.attrs.has_key((None,"type")):
self.log(MissingTypeAttr({"parent":self.parent.name, "element":self.name, "attr":"type"}))
if self.type in ['text','html','xhtml'] and not self.attrs.has_key((None,"src")):
pass
elif self.type and not self.mime_re.match(self.type):
self.log(InvalidMIMEType({"parent":self.parent.name, "element":self.name, "attr":"type", "value":self.type}))
else:
self.log(ValidMIMEAttribute({"parent":self.parent.name, "element":self.name, "attr":"type", "value":self.type}))
if not self.xmlLang:
self.log(MissingDCLanguage({"parent":self.name, "element":"xml:lang"}))
def validate(self):
if self.type in ['text','xhtml']:
if self.type=='xhtml':
nonhtml.validate(self, NotInline)
else:
nonhtml.validate(self, ContainsUndeclaredHTML)
else:
if self.type.find('/') > -1 and not (
self.type.endswith('+xml') or self.type.endswith('/xml') or
self.type.startswith('text/')):
import base64
try:
self.value=base64.decodestring(self.value)
if self.type.endswith('/html'): self.type='html'
except:
self.log(NotBase64({"parent":self.parent.name, "element":self.name,"value":self.value}))
if self.type=='html' or self.type.endswith("/html"):
self.validateSafe(self.value)
if self.type.endswith("/html"):
if self.value.find("<html")<0 and not self.attrs.has_key((None,"src")):
self.log(HtmlFragment({"parent":self.parent.name, "element":self.name,"value":self.value, "type":self.type}))
else:
nonhtml.validate(self, ContainsUndeclaredHTML)
if not self.value and len(self.children)==0 and not self.attrs.has_key((None,"src")):
self.log(NotBlank({"parent":self.parent.name, "element":self.name}))
def textOK(self):
if self.children: validatorBase.textOK(self)
def characters(self, string):
for c in string:
if 0x80 <= ord(c) <= 0x9F or c == u'\ufffd':
from validators import BadCharacters
self.log(BadCharacters({"parent":self.parent.name, "element":self.name}))
if (self.type=='xhtml') and string.strip() and not self.value.strip():
self.log(MissingXhtmlDiv({"parent":self.parent.name, "element":self.name}))
validatorBase.characters(self,string)
def startElementNS(self, name, qname, attrs):
if (self.type<>'xhtml') and not (
self.type.endswith('+xml') or self.type.endswith('/xml')):
self.log(UndefinedElement({"parent":self.name, "element":name}))
if self.type=="xhtml":
if name<>'div' and not self.value.strip():
self.log(MissingXhtmlDiv({"parent":self.parent.name, "element":self.name}))
elif qname not in ["http://www.w3.org/1999/xhtml"]:
self.log(NotHtml({"parent":self.parent.name, "element":self.name, "message":"unexpected namespace: %s" % qname}))
if self.type=="application/xhtml+xml":
if name<>'html':
self.log(HtmlFragment({"parent":self.parent.name, "element":self.name,"value":self.value, "type":self.type}))
elif qname not in ["http://www.w3.org/1999/xhtml"]:
self.log(NotHtml({"parent":self.parent.name, "element":self.name, "message":"unexpected namespace: %s" % qname}))
if self.attrs.has_key((None,"mode")):
if self.attrs.getValue((None,"mode")) == 'escaped':
self.log(NotEscaped({"parent":self.parent.name, "element":self.name}))
if name=="div" and qname=="http://www.w3.org/1999/xhtml":
handler=diveater()
else:
handler=eater()
self.children.append(handler)
self.push(handler, name, attrs)
# treat xhtml:div as part of the content for purposes of detecting escaped html
class diveater(eater):
def __init__(self):
eater.__init__(self)
self.mixed = False
def textOK(self):
pass
def characters(self, string):
validatorBase.characters(self, string)
def startElementNS(self, name, qname, attrs):
if not qname:
self.log(MissingNamespace({"parent":"xhtml:div", "element":name}))
self.mixed = True
eater.startElementNS(self, name, qname, attrs)
def validate(self):
if not self.mixed: self.parent.value += self.value
class content(textConstruct):
def maptype(self):
if self.type == 'multipart/alternative':
self.log(InvalidMIMEType({"parent":self.parent.name, "element":self.name, "attr":"type", "value":self.type}))

View file

@ -1,50 +0,0 @@
Options +ExecCGI -MultiViews
AddHandler cgi-script .cgi
AddType image/x-icon ico
RewriteRule ^check$ check.cgi
DirectoryIndex index.html check.cgi
# MAP - bad bots are killing the server (everybody links to their validation results and the bots dutifully crawl it)
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} BecomeBot [OR]
RewriteCond %{HTTP_USER_AGENT} Crawler [OR]
RewriteCond %{HTTP_USER_AGENT} FatBot [OR]
RewriteCond %{HTTP_USER_AGENT} Feed24 [OR]
RewriteCond %{HTTP_USER_AGENT} Gigabot [OR]
RewriteCond %{HTTP_USER_AGENT} Googlebot [OR]
RewriteCond %{HTTP_USER_AGENT} htdig [OR]
RewriteCond %{HTTP_USER_AGENT} HttpClient
RewriteCond %{HTTP_USER_AGENT} HTTrack [OR]
RewriteCond %{HTTP_USER_AGENT} IQSearch [OR]
RewriteCond %{HTTP_USER_AGENT} msnbot [OR]
RewriteCond %{HTTP_USER_AGENT} NaverBot [OR]
RewriteCond %{HTTP_USER_AGENT} OmniExplorer [OR]
RewriteCond %{HTTP_USER_AGENT} SietsCrawler [OR]
RewriteCond %{HTTP_USER_AGENT} Thunderbird [OR]
RewriteCond %{HTTP_USER_AGENT} TurnitinBot [OR]
RewriteCond %{HTTP_USER_AGENT} User-Agent [OR]
RewriteCond %{HTTP_USER_AGENT} Yahoo!.Slurp [OR]
RewriteRule check - [F,L]
# fastcgi
RewriteCond /home/rubys/public_html/fvstat/status -f
RewriteRule check.cgi(.*)$ http://localhost:8080/rubys/feedvalidator.org/$1 [P]
<Files check.cgi>
Deny from feeds01.archive.org
Deny from feedvalidator.org
Deny from new.getfilesfast.com
Deny from gnat.yodlee.com
Deny from master.macworld.com
Deny from 62.244.248.104
Deny from 207.97.204.219
Deny from ik63025.ikexpress.com
Deny from 65-86-180-70.client.dsl.net
Deny from vanadium.sabren.com
</Files>
<Files config.py>
ForceType text/plain
</Files>

View file

@ -1,26 +0,0 @@
The Feed Validator (includig all code, tests, and documentation) is released
under the following license:
----- begin license block -----
Copyright (c) 2002-2006, Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
----- end license block -----

View file

@ -1,9 +0,0 @@
Some tests, and some functionality, will not be enabled unless a full set
of 32-bit character encodings are available through Python.
The package 'iconvcodec' provides the necessary codecs, if your underlying
operating system supports them. Its web page is at
<http://cjkpython.i18n.org/#iconvcodec>, and a range of packages are
provided.
Python 2.3.x is required, for its Unicode support.

View file

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<definitions
targetNamespace="http://feedvalidator.org/"
xmlns:validator="http://feedvalidator.org/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema elementFormDefault="qualified"
targetNamespace="http://feedvalidator.org/">
<xsd:complexType name="Request">
<xsd:sequence>
<xsd:any namespace="##other"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Message">
<xsd:sequence>
<xsd:element name="level" type="xsd:string"/>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="line" type="xsd:string"/>
<xsd:element name="column" type="xsd:string"/>
<xsd:element name="msgcount" type="xsd:string"/>
<xsd:element name="text" type="xsd:string"/>
<xsd:any minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Response">
<xsd:sequence>
<xsd:element name="message" type="validator:Message"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="request" type="validator:Request"/>
<xsd:element name="response" type="validator:Response"/>
</xsd:schema>
</types>
<message name="validateIn">
<part name="request" element="validator:request" />
</message>
<message name="validateOut">
<part name="response" element="validator:response" />
</message>
<portType name="RSSValidatorSoap">
<operation name="validate">
<input message="validator:validateIn" />
<output message="validator:validateOut" />
</operation>
</portType>
<binding name="soap" type="validator:RSSValidatorSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="validate">
<soap:operation soapAction="urn:validate" style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="RSSValidator">
<port name="RSSValidatorSoap" binding="validator:soap">
<soap:address location="http://feedvalidator.org/" />
</port>
</service>
</definitions>

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>About the Feed Validator</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css" media="screen">@import "css/common.css";
@import "css/documentation.css";</style>
<script type="text/javascript"><!-- --></script>
</head>
<body>
<div id="logo">
<h1><a href="/"><span id="feed"><span id="f">F</span><span id="e1">E</span><span id="e2">E</span></span><span id="d">D</span> Validator</a></h1>
<p>About</p>
<a class="skip" href="#startnavigation">Jump to navigation</a>
</div> <!--logo-->
<div id="main">
<p>On this page:</p>
<ul>
<li><a href="#what">What is this?</a></li>
<li><a href="#why">Why a validator?</a></li>
<li><a href="#how">What does it validate?</a></li>
<li><a href="#who">Who wrote it?</a></li>
<li><a href="#where">Can I run it locally?</a></li>
<li><a href="#when">Can I tell you something?</a></li>
</ul>
<h2 id="what">What is this?</h2>
<p>This is a validator for syndicated feeds. It works with RSS 0.90, 0.91, 0.92, 0.93, 0.94, 1.0, 1.1, and 2.0. It also validates Atom feeds.</p>
<p>To use it, simply enter the address of your feed and click Validate. If the validator finds any problems in your feed, it will give you messages for each type of problem and highlight where the problem first occurs in your feed. If you're unsure what a message means, click the "help" link next to the message for a fuller explanation.</p>
<h2 id="why">Why a validator?</h2>
<p>Despite its relatively simple nature, RSS is poorly implemented by many tools. This validator is an attempt to codify the specification (literally, to translate it into code) to make it easier to know when you're producing RSS correctly, and to help you fix it when you're not.</p>
<p>The validator also supports the IETF standard Atom format for syndicated feeds. Early adopters who wish to support Atom should use the validator to make sure they generate it properly from day 1.</p>
<p>There are validators for other web technologies, such as <a href="http://validator.w3.org/">HTML</a>, <a href="http://jigsaw.w3.org/css-validator/">CSS</a>, and <a href="http://webxact.watchfire.com/">accessibility guidelines</a>, and these have all proven quite popular. As personal news syndication is becoming more widespread, we saw a need for a comprehensive but easy-to-use validator for syndicated feeds.</p>
<h2 id="how">What does it validate?</h2>
<p>It validates RSS feeds against the rules defined in the <a href="/docs/rss2.html">RSS 2.0 specification</a>. It also validates elements of commonly used namespaces:</p>
<ul>
<li>blogChannel</li>
<li>Dublin Core</li>
<li>itunes</li>
<li>mod_admin</li>
<li>mod_syndication</li>
<li>mod_content (<code>content:encoded</code> only)</li>
</ul>
<p>For Atom feeds, it validates against <a href="http://www.ietf.org/rfc/rfc4287">RFC 4287</a>, which describes version 1.0 of the Atom feed format.</p>
<p>The <a href="/docs/">documentation index</a> lists all the error messages that the validator produces. You can also download the entire test suite that was used to create the validator (see below).</p>
<h2 id="who">Who wrote it?</h2>
<p>The validator was conceived and designed by <a href="http://diveintomark.org/">Mark Pilgrim</a>, who also wrote most of the test cases and designed the web front end. Much of the actual back end coding was done by <a href="http://intertwingly.net/blog/">Sam Ruby</a>.</p>
<a name="opensource" id="opensource"></a>
<h2 id="where">Can I run it locally?</h2>
<p>Yes. The validator is open source, written in Python, and distributed under the <a href="LICENSE">MIT license</a>. To run it, you will need <a href="http://python.org/">Python 2.3</a> or later, and an XML parser. Most Python distributions include a minimal XML parser which will work just fine. Mac OS X 10.2 users should install <a href="http://sourceforge.net/projects/pyxml/">PyXML</a>.</p>
<p>You can find more information in our convenient <a href="docs/howto/install_and_run.html">HowTo</a>.</p>
<h2 id="when">Can I tell you something?</h2>
<p>Sure! The best way to provide feedback on the validator is on the <a href="http://lists.sourceforge.net/lists/listinfo/feedvalidator-users">Sourceforge mailing list</a>.</p>
</div><!--main-->
<div class="centered">
<a name="startnavigation" id="startnavigation"></a>
<div class="navbarWrapper">
<div class="navbarContent">
<img class="borderTL" src="/images/borderTL.gif" alt="" width="14" height="14" />
<img class="borderTR" src="/images/borderTR.gif" alt="" width="14" height="14" />
<p>
<a href="/">Home</a> &middot;
<a href="about.html">About</a> &middot;
<a href="news/">News</a> &middot;
<a href="docs/">Docs</a> &middot;
<a href="terms.html">Terms</a>
</p>
<div class="roundedCornerSpacer">&nbsp;</div>
</div><!-- .content -->
<div class="bottomCorners">
<img class="borderBL" src="/images/borderBL.gif" alt="" width="14" height="14" />
<img class="borderBR" src="/images/borderBR.gif" alt="" width="14" height="14" />
</div><!-- .bottomCorners -->
</div><!-- .contentWrapper -->
</div><!-- .centered -->
<div class="centered">
<address>Copyright © 2002-6
<a href="http://www.intertwingly.net/blog/">Sam Ruby</a>,
<a href="http://diveintomark.org/">Mark Pilgrim</a>,
<a href="http://www.kafsemo.org/">Joseph Walton</a>, and
<a href="http://philringnalda.com/">Phil Ringnalda</a>
</address>
</div>
</body>
</html>

View file

@ -1,83 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Feed Validator: alternate banners</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css" media="screen">@import "css/common.css";
@import "css/documentation.css";</style>
<script type="text/javascript"><!-- --></script>
</head>
<body>
<div id="logo">
<h1><a href="/"><span id="feed"><span id="f">F</span><span id="e1">E</span><span id="e2">E</span></span><span id="d">D</span> Validator</a></h1>
<p>Alternate banners</p>
<a class="skip" href="#startnavigation">Jump to navigation</a>
</div> <!--logo-->
<div id="main">
<h2>Alternate "Valid RSS" banners</h2>
<p>If the default "valid RSS" banner is not your style, you can use any of these, or anything else you design, or nothing at all. The fact that you care enough to validate your feed is the important part; how you advertise it is up to you.</p>
<p style="line-height:300%">
<img alt="Brockman Bulger's entry" title="by Brockman Bulger" src="/images/valid-rss-bbulger.png" width="88" height="31" /> &nbsp;
<img alt="Dylan Parker's entry #2" title="by Dylan Parker" src="/images/valid-rss-dylan2.gif" width="88" height="31" /> &nbsp;
<img alt="Neil Lee's entry with white background" title="by Neil Lee" src="/images/valid-rss-white-neil.gif" width="88" height="31" /> &nbsp;
<img alt="Dougal Campbell's entry with white background" title="by Dougal Campbell" src="/images/valid-rss-white-dougal.gif" width="88" height="31" /> &nbsp;
<img alt="Robert Guertin's entry" title="by Robert Guertin" src="/images/valid-rss-robert.jpg" width="88" height="31" /> &nbsp;
<img alt="Jon Wiley's entry" title="by Jon Wiley" src="/images/valid-rss-jon-wiley.gif" width="88" height="31" /> &nbsp;
<img alt="Jonathon Delacour's entry" title="by Jonathon Delacour" src="/images/valid-rss-jonathan.gif" width="88" height="31" /> &nbsp;
<img alt="Lee O'Mara's entry" title="by Lee O'Mara" src="/images/valid-rss-lee.gif" width="88" height="31" /> &nbsp;
<img alt="Aaron Swartz's entry" title="by Aaron Swartz" src="/images/valid-rss-aaron.png" width="88" height="31" /> &nbsp;
<img alt="Dylan Parker's entry #1" title="by Dylan Parker" src="/images/valid-rss-dylan1.gif" width="88" height="31" /> &nbsp;
<img alt="Shelley Powers' entry" title="by Shelley Powers" src="/images/valid-rss-shelley.gif" width="88" height="31" /> &nbsp;
<img alt="Walt Dickinson's entry with orange background" title="by Walt Dickinson" src="/images/valid-rss-orange-walt.gif" width="88" height="31" /> &nbsp;
<img alt="Walt Dickinson's entry with red background" title="by Walt Dickinson" src="/images/valid-rss-red-walt.gif" width="88" height="31" /> &nbsp;
<img alt="Dylan Parker's entry #4" title="by Dylan Parker" src="/images/valid-rss-dylan4.gif" width="88" height="31" /> &nbsp;
<img alt="Walk Dickinson's entry with grey background" title="by Walt Dickinson" src="/images/valid-rss-grey-walt.gif" width="88" height="31" /> &nbsp;
<img alt="Neil Lee's entry with maroon background" title="by Neil Lee" src="/images/valid-rss-neil.gif" width="88" height="31" /> &nbsp;
<img alt="Dylan Parker's entry #3" title="by Dylan Parker" src="/images/valid-rss-dylan3.gif" width="88" height="31" /> &nbsp;
<img alt="Martin Murtonen's entry" title="by Martin Murtonen" src="/images/valid-rss-martin.gif" /> &nbsp;
<img alt="Dougal Campbell's entry with black background" title="by Dougal Campbell" src="/images/valid-rss-black-dougal.gif" width="88" height="31" /> &nbsp;
<img alt="Nicholas Avenell's entry" title="by Nicholas Avenell" src="/images/valid-rss-nicholas.png" width="88" height="31" /> &nbsp;
<img alt="Aaron Swartz's entry, based on a design by antipixel.com" title="by Aaron Swartz (in the style of antipixel.com)" src="/images/valid-rss-antipixel.png" width="80" height="15" /> &nbsp;
<img alt="Jack Greenwood's entry" title="by Jack Greenwood" src="/images/kiss-my-rss.gif" width="88" height="31" /> &nbsp;
</p>
<p>Designers who wish to have their "valid RSS" banner listed here should email it to <a href="mailto:feed-validator@diveintomark.org">feed-validator@diveintomark.org</a>.</p>
</div><!--main-->
<div class="centered">
<a name="startnavigation" id="startnavigation"></a>
<div class="navbarWrapper">
<div class="navbarContent">
<img class="borderTL" src="/images/borderTL.gif" alt="" width="14" height="14" />
<img class="borderTR" src="/images/borderTR.gif" alt="" width="14" height="14" />
<p>
<a href="./">Home</a> &middot;
<a href="./about.html">About</a> &middot;
<a href="./news/">News</a> &middot;
<a href="./docs/">Docs</a> &middot;
<a href="./terms.html">Terms</a>
</p>
<div class="roundedCornerSpacer">&nbsp;</div>
</div><!-- .content -->
<div class="bottomCorners">
<img class="borderBL" src="/images/borderBL.gif" alt="" width="14" height="14" />
<img class="borderBR" src="/images/borderBR.gif" alt="" width="14" height="14" />
</div><!-- .bottomCorners -->
</div><!-- .contentWrapper -->
</div><!-- .centered -->
<div class="centered">
<address>Copyright &copy; 2002-3 <a href="http://diveintomark.org/">Mark Pilgrim</a> and <a href="http://www.intertwingly.net/blog/">Sam Ruby</a></address>
</div>
</body>
</html>

View file

@ -1,355 +0,0 @@
#!/usr/bin/env python
from config import *
import cgi, sys, os, urlparse, sys, re, urllib
import cgitb
cgitb.enable()
import codecs
ENCODING='UTF-8'
sys.stdout = codecs.getwriter(ENCODING)(sys.stdout)
# Used for CGI parameters
decUTF8 = codecs.getdecoder('utf-8')
decW1252 = codecs.getdecoder('windows-1252')
if PYDIR not in sys.path:
sys.path.insert(0, PYDIR)
if WEBDIR not in sys.path:
sys.path.insert(0, WEBDIR)
if SRCDIR not in sys.path:
sys.path.insert(0, SRCDIR)
import feedvalidator
from feedvalidator.logging import FEEDTYPEDISPLAY, VALIDFEEDGRAPHIC
from feedvalidator.logging import Info, Warning, Error, ValidationFailure
from feedvalidator.logging import TYPE_ATOM_ENTRY, TYPE_OPENSEARCH, TYPE_XRD
def applyTemplate(templateFile, params={}):
params['CSSURL'] = CSSURL
fsock = open(os.path.join(WEBDIR, 'templates', templateFile))
data = fsock.read() % params
fsock.close()
return data.encode('utf-8')
def sanitizeURL(url):
# Allow feed: URIs, as described by draft-obasanjo-feed-URI-scheme-02
if url.lower().startswith('feed:'):
url = url[5:]
if url.startswith('//'):
url = 'http:' + url
if not url.split(':')[0].lower() in ['http','https']:
url = 'http://%s' % url
url = url.strip()
# strip user and password
url = re.sub(r'^(\w*://)[-+.\w]*(:[-+.\w]+)?@', r'\1' ,url)
return url
def escapeURL(url):
parts = list(urlparse.urlparse(url))
safe = ['/', '/:@', '/', '/', '/?&=;', '/']
for i in range(0,len(parts)):
parts[i] = urllib.quote(urllib.unquote(parts[i]),safe[i])
url = cgi.escape(urlparse.urlunparse(parts))
try:
return url.decode('idna')
except:
return url
import feedvalidator.formatter.text_html
def buildCodeListing(events, rawdata, url):
# print feed
codelines = []
linenum = 1
linesWithErrors = [e.params.get('line', 0) for e in events]
for line in rawdata.split('\n'):
line = feedvalidator.formatter.text_html.escapeAndMark(line)
if not line: line = '&nbsp;'
linetype = linenum in linesWithErrors and "b" or "a"
codelines.append(applyTemplate('code_listing_line.tmpl', {"line":line, "linenum":linenum, "linetype":linetype}).decode('utf-8'))
linenum += 1
codelisting = "".join(codelines)
return applyTemplate('code_listing.tmpl', {"codelisting":codelisting, "url":escapeURL(url)})
def yieldEventList(output):
errors, warnings = output.getErrors(), output.getWarnings()
yield output.header()
for o in output.getErrors():
yield o.encode('utf-8')
if errors and warnings:
yield output.footer()
if len(warnings) == 1:
yield applyTemplate('andwarn1.tmpl')
else:
yield applyTemplate('andwarn2.tmpl')
yield output.header()
for o in output.getWarnings():
yield o.encode('utf-8')
yield output.footer()
from feedvalidator.formatter.text_html import Formatter
def postvalidate(url, events, rawdata, feedType, autofind=1):
"""returns dictionary including 'url', 'events', 'rawdata', 'output', 'specialCase', 'feedType'"""
# filter based on compatibility level
from feedvalidator import compatibility
filterFunc = compatibility.AA # hardcoded for now
events = filterFunc(events)
specialCase = None
formattedOutput = Formatter(events, rawdata)
if formattedOutput:
# check for special cases
specialCase = compatibility.analyze(events, rawdata)
if (specialCase == 'html') and autofind:
try:
try:
import feedfinder
class NotARobot:
base=url
def get(self, url):
if url == self.base: return rawdata
sock=urllib.urlopen(url)
data=sock.read()
sock.close()
return data
feedfinder._gatekeeper = NotARobot()
rssurls = feedfinder.getFeeds(url)
except:
rssurls = [url]
if rssurls:
url = rssurls[0]
params = feedvalidator.validateURL(url, firstOccurrenceOnly=1, wantRawData=1)
events = params['loggedEvents']
rawdata = params['rawdata']
feedType = params['feedType']
return postvalidate(url, events, rawdata, feedType, autofind=0)
except:
pass
return {"url":url, "events":events, "rawdata":rawdata, "output":formattedOutput, "specialCase":specialCase, "feedType":feedType}
def checker_app(environ, start_response):
method = environ['REQUEST_METHOD'].lower()
contentType = environ.get('CONTENT_TYPE', None)
output_option = ''
if (method == 'get') or (contentType and cgi.parse_header(contentType)[0].lower() == 'application/x-www-form-urlencoded'):
fs = cgi.FieldStorage(fp=environ.get('wsgi.input',None), environ=environ)
url = fs.getvalue("url") or ''
try:
if url: url = url.decode('utf-8').encode('idna')
except:
pass
manual = fs.getvalue("manual") or 0
rawdata = fs.getvalue("rawdata") or ''
output_option = fs.getvalue("output") or ''
# XXX Should use 'charset'
try:
rawdata = decUTF8(rawdata)[0]
except UnicodeError:
rawdata = decW1252(rawdata)[0]
rawdata = rawdata[:feedvalidator.MAXDATALENGTH].replace('\r\n', '\n').replace('\r', '\n')
else:
url = None
manual = None
rawdata = None
if (output_option == "soap12"):
# SOAP
try:
if ((method == 'post') and (not rawdata)):
params = feedvalidator.validateStream(sys.stdin, contentType=contentType)
elif rawdata :
params = feedvalidator.validateString(rawdata, firstOccurrenceOnly=1)
elif url:
url = sanitizeURL(url)
params = feedvalidator.validateURL(url, firstOccurrenceOnly=1, wantRawData=1)
events = params['loggedEvents']
feedType = params['feedType']
# filter based on compatibility level
from feedvalidator import compatibility
filterFunc = compatibility.AA # hardcoded for now
events = filterFunc(events)
events_error = list()
events_warn = list()
events_info = list()
# format as xml
from feedvalidator.formatter.text_xml import Formatter as xmlformat
output = xmlformat(events)
for event in events:
if isinstance(event,Error): events_error.append(output.format(event))
if isinstance(event,Warning): events_warn.append(output.format(event))
if isinstance(event,Info): events_info.append(output.format(event))
if len(events_error) > 0:
validation_bool = "false"
else:
validation_bool = "true"
from datetime import datetime
right_now = datetime.now()
validationtime = str( right_now.isoformat())
body = applyTemplate('soap.tmpl', {
'errorlist':"\n".join( events_error), 'errorcount': str(len(events_error)),
'warninglist':"\n".join( events_warn), 'warningcount': str(len(events_warn)),
'infolist':"\n".join( events_info), 'infocount': str(len(events_info)),
'home_url': HOMEURL, 'url': url, 'date_time': validationtime, 'validation_bool': validation_bool
})
start_response('200 OK', [('Content-type', 'application/soap+xml; charset=' + ENCODING)])
yield body
except:
import traceback
tb = ''.join(apply(traceback.format_exception, sys.exc_info()))
from feedvalidator.formatter.text_xml import xmlEncode
start_response('500 Internal Error', [('Content-type', 'text/xml; charset=' + ENCODING)])
yield applyTemplate('fault.tmpl', {'code':sys.exc_info()[0],
'string':sys.exc_info()[1], 'traceback':xmlEncode(tb)})
else:
start_response('200 OK', [('Content-type', 'text/html; charset=' + ENCODING)])
if url or rawdata:
# validate
goon = 0
if rawdata:
# validate raw data (from text form)
try:
params = feedvalidator.validateString(rawdata, firstOccurrenceOnly=1)
events = params['loggedEvents']
feedType = params['feedType']
goon = 1
except ValidationFailure, vfv:
yield applyTemplate('header.tmpl', {'title':'Feed Validator Results: %s' % escapeURL(url)})
yield applyTemplate('manual.tmpl', {'rawdata':escapeURL(url)})
output = Formatter([vfv.event], None)
for item in yieldEventList(output):
yield item
yield applyTemplate('error.tmpl')
except:
yield applyTemplate('header.tmpl', {'title':'Feed Validator Results: %s' % escapeURL(url)})
yield applyTemplate('manual.tmpl', {'rawdata':escapeURL(url)})
yield applyTemplate('error.tmpl')
else:
url = sanitizeURL(url)
try:
params = feedvalidator.validateURL(url, firstOccurrenceOnly=1, wantRawData=1)
events = params['loggedEvents']
rawdata = params['rawdata']
feedType = params['feedType']
goon = 1
except ValidationFailure, vfv:
yield applyTemplate('header.tmpl', {'title':'Feed Validator Results: %s' % escapeURL(url)})
yield applyTemplate('index.tmpl', {'value':escapeURL(url)})
output = Formatter([vfv.event], None)
for item in yieldEventList(output):
yield item
yield applyTemplate('error.tmpl')
except:
yield applyTemplate('header.tmpl', {'title':'Feed Validator Results: %s' % escapeURL(url)})
yield applyTemplate('index.tmpl', {'value':escapeURL(url)})
yield applyTemplate('error.tmpl')
if goon:
# post-validate (will do RSS autodiscovery if needed)
validationData = postvalidate(url, events, rawdata, feedType)
# write output header
url = validationData['url']
feedType = validationData['feedType']
rawdata = validationData['rawdata']
yield applyTemplate('header.tmpl', {'title':'Feed Validator Results: %s' % escapeURL(url)})
if manual:
yield applyTemplate('manual.tmpl', {'rawdata':cgi.escape(rawdata)})
else:
yield applyTemplate('index.tmpl', {'value':escapeURL(url)})
output = validationData.get('output', None)
# print special case, if any
specialCase = validationData.get('specialCase', None)
if specialCase:
yield applyTemplate('%s.tmpl' % specialCase)
msc = output.mostSeriousClass()
# Explain the overall verdict
if msc == Error:
from feedvalidator.logging import ObsoleteNamespace
if len(output.getErrors())==1 and \
isinstance(output.data[0],ObsoleteNamespace):
yield applyTemplate('notsupported.tmpl')
else:
yield applyTemplate('invalid.tmpl')
elif msc == Warning:
yield applyTemplate('warning.tmpl')
elif msc == Info:
yield applyTemplate('info.tmpl')
# Print any issues, whether or not the overall feed is valid
if output:
for item in yieldEventList(output):
yield item
# print code listing
yield buildCodeListing(validationData['events'], validationData['rawdata'], url)
# As long as there were no errors, show that the feed is valid
if msc != Error:
# valid
htmlUrl = escapeURL(urllib.quote(url))
try:
htmlUrl = htmlUrl.encode('idna')
except:
pass
docType = 'feed'
if feedType == TYPE_ATOM_ENTRY: docType = 'entry'
if feedType == TYPE_XRD: docType = 'document'
if feedType == TYPE_OPENSEARCH: docType = 'description document'
yield applyTemplate('valid.tmpl', {"url":htmlUrl, "srcUrl":htmlUrl, "feedType":FEEDTYPEDISPLAY[feedType], "graphic":VALIDFEEDGRAPHIC[feedType], "HOMEURL":HOMEURL, "docType":docType})
else:
# nothing to validate, just write basic form
yield applyTemplate('header.tmpl', {'title':'Feed Validator for Atom and RSS'})
if manual:
yield applyTemplate('manual.tmpl', {'rawdata':''})
else:
yield applyTemplate('index.tmpl', {'value':'http://'})
yield applyTemplate('special.tmpl', {})
yield applyTemplate('navbar.tmpl')
yield applyTemplate('footer.tmpl')
if __name__ == "__main__":
if len(sys.argv)==1 or not sys.argv[1].isdigit():
def start_response(status, headers):
print 'Status: %s\r\n' % status,
for header,value in headers:
print '%s: %s\r\n' % (header, value),
print
for output in checker_app(os.environ, start_response):
print output.decode('utf-8')
else:
# export HTTP_HOST=http://feedvalidator.org/
# export SCRIPT_NAME=check.cgi
# export SCRIPT_FILENAME=/home/rubys/svn/feedvalidator/check.cgi
import fcgi
port=int(sys.argv[1])
fcgi.WSGIServer(checker_app, bindAddress=("127.0.0.1", port)).run()

View file

@ -1,22 +0,0 @@
# Default URL of the validator itself... feel free to beautify as you like
import os
HOMEURL = os.environ['HTTP_HOST'] + os.environ['SCRIPT_NAME']
if not HOMEURL.startswith('http://'): HOMEURL = 'http://' + HOMEURL
# This is where the CGI itself is... other supporting scripts (like
# feedfinder) may be placed here.
WEBDIR = '/'.join(os.environ['SCRIPT_FILENAME'].split('/')[0:-1])
# This following value is primarily used for setting up the other values...
HOMEDIR = WEBDIR
# This is where local python libraries are installed. This may be useful
# for locating a locally installed libxml2 library, for example...
PYDIR = HOMEDIR + r'/lib/python/'
# This is where the feedvalidator code lives...
SRCDIR = WEBDIR + r'/src'
# The web location prefix of the docs and CSS, relative to check.cgi
DOCSURL='docs'
CSSURL='css'

View file

@ -1,170 +0,0 @@
/* ----- general ----- */
body {
background: white;
color: black;
font-size: 100%;
/* UNIX-friendly fonts from <http://www.realworldstyle.com/fonts.html> */
font-family: "Lucida Grande", "Trebuchet MS", Verdana, Geneva, Lucida, Helvetica, sans-serif;
}
a.skip {
display: none;
}
div.centered {
text-align: center;
}
p.centered {
margin-left: auto;
margin-right: auto;
}
/* ----- logo ----- */
#logo {
text-align: center;
padding-bottom: 10px;
padding-top: 20px;
}
h1 {
margin-top: 0;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
padding: 0;
background-color: transparent;
color: #444;
font-size: 400%;
font-family: LuciduxSerif, Georgia, "Book Antiqua", Palatino, serif;
font-weight: bold;
}
h1 a {
text-decoration: none;
}
#rss {
letter-spacing: 0.2em;
}
#f {
background-color: transparent;
color: #cc0000;
}
#e1 {
background-color: transparent;
color: #009900;
}
#e2 {
background-color: transparent;
color: #3366cc;
}
#d {
background-color: transparent;
color: #cc6633;
}
#logo p {
margin-top: 0.5em;
margin-bottom: 0;
text-transform: uppercase;
letter-spacing: 0.2em;
font-weight: bold;
}
/* ----- navbar ----- */
/* rounded corners from <http://www.albin.net/CSS/RoundedCorners/> */
.navbarWrapper {
margin-top: 10px;
margin-bottom: 30px;
margin-left: auto;
margin-right: auto;
width: 50%;
padding: 0px;
border: 0px;
}
.navbarContent {
margin: 0px;
padding: 0px;
border: 1px solid #000000;
background-color: #ffffff;
color: #000000;
}
.navbarContent p {
margin-top: 5px;
margin-bottom: 5px;
}
.roundedCornerSpacer {
margin: 0px; padding: 0px; border: 0px;
font-size: 1px; line-height: 1px;
clear: both;
}
.borderTL, .borderTR, .borderBL, .borderBR {
width: 14px; height: 14px;
padding: 0px; border: 0px;
z-index: 99;
}
.borderTL, .borderBL { float: left; clear: both; }
.borderTR, .borderBR { float: right; clear: right; }
.borderTL { margin: -1px 0px 0px -1px; }
.borderTR { margin: -1px -1px 0px 0px; }
.borderBL { margin: -14px 0px 0px 0px; }
.borderBR { margin: -14px 0px 0px 0px; }
.borderTL {
margin-left: -4px;
ma\rgin-left: -1px;
}
html>body .borderTL {
margin-left: -1px;
}
.borderTR {
margin-right: -4px;
ma\rgin-right: -1px;
}
html>body .borderTR {
margin-right: -1px;
}
.borderBL {
margin-left: -3px;
ma\rgin-left: 0px;
}
html>body .borderBL {
margin-left: 0px;
}
.borderBR {
margin-right: -3px;
ma\rgin-right: 0px;
}
html>body .borderBR {
margin-right: 0px;
}
/* ----- footer ----- */
address {
font-size: x-small;
font-style: normal;
}
#poweredby {
font-size: x-small;
background: transparent;
color: #333;
}
code {
font-size: larger;
}

View file

@ -1,16 +0,0 @@
#main h2 {
font-size: 120%;
}
#main .docbody {
margin-left: 2em;
line-height: 140%;
}
#main p.meta {
font-size: xx-small;
background: transparent;
color: #999;
margin-top: 1em;
margin-left: 0;
}

View file

@ -1,27 +0,0 @@
#main .newsbody {
line-height: 140%;
}
#main h2 {
margin-bottom: 0;
font-size: 120%;
}
#main p.dateheader {
font-size: xx-small;
background: transparent;
color: #333;
margin-top: 0;
}
#main p.dateheader a {
text-decoration: none;
background: transparent;
color: #999;
border-bottom: 1px dotted #999;
}
#main p.dateheader a:hover {
background: transparent;
color: #333;
}

View file

@ -1,66 +0,0 @@
/* ----- validation form ----- */
form#validation {
width: 550px;
margin-left: auto;
margin-right: auto;
margin-top: 30px;
margin-bottom: 50px;
}
/* ----- results ----- */
.message {
background-color: yellow;
color: black;
}
.marker {
background-color: transparent;
color: #cc0000;
}
.badOctet {
font-weight: bold;
color: inherit;
background: red;
}
div.specialmessage {
border: 1px solid black;
background-color: #ddd;
color: black;
margin-left: 2em;
margin-right: 2em;
padding-left: 1em;
padding-right: 1em;
}
/* ----- code listing ----- */
/* code listing from <http://development.incutio.com/simon/numbered-code-experiment.html> */
ol.codeListing {
font-family: monospace;
color: green;
background-color: #fff;
list-style-type: decimal-leading-zero;
list-style-position: inside;
width: 90%;
}
ol.codeListing li {
background-color: #eee;
color: black;
margin: 2px;
}
ol.codeListing li code {
background: transparent;
color: black;
margin-left: 2em;
}
ol.codeListing li code.b {
background: yellow;
color: black;
}

View file

@ -1,9 +0,0 @@
all: docs ../docs/index.html
docs: $(patsubst %.xml,../docs/%.html, error/*.xml warning/*.xml info/*.xml)
../docs/%.html: %.xml
./build-html-docs.py template.html ../docs $<
../docs/index.html: docs-index-header.html error/*.xml warning/*.xml info/*.xml docs-index-footer.html build-docs-index.py
./build-docs-index.py

View file

@ -1,64 +0,0 @@
#!/usr/bin/python
# Put a header and a footer on a list of all documented diagnostics,
# linking to their pages.
# Note that this script has lots of hardcoded paths, needs to be run
# from the docs-xml directory, and modifies the index.html in docs.
from os import listdir
from os import path
import re
from sys import stderr
basedir = '.'
messageRe = re.compile("<div id='message'>\n<p>(.*)</p>\n</div>")
def getMessage(fn):
f = open(fn)
txt = f.read()
f.close()
m = messageRe.search(txt)
return m.group(1)
of = open('../docs/index.html', 'w')
def printLine(hr, msg):
of.write('<li><a href="%s">%s</a></li>' % (hr, msg))
of.write("\n")
f = open('docs-index-header.html')
of.write(f.read())
f.close()
of.write("<h2>Validator messages</h2>\n")
for (type, title) in [('error', 'Errors'), ('warning', 'Warnings'), ('info', 'Information')]:
p = path.join(basedir, type)
allMsgs = []
for f in listdir(p):
(name,ext) = path.splitext(f)
if ext != '.xml':
continue
msg = getMessage(path.join(p, f))
allMsgs.append([name, msg])
allMsgs.sort()
of.write("\n<h3>%s</h3>\n" % title)
of.write("<ul>\n")
for (f, msg) in allMsgs:
printLine(type + '/' + f + '.html', msg)
of.write("</ul>\n")
f = open('docs-index-footer.html')
of.write(f.read())
f.close()

View file

@ -1,100 +0,0 @@
#!/usr/bin/python
# Given a template (with a specific format), a target document root and a set of formatted XML
# documents, generate HTML documentation for public web access.
# Extracts information from XML using regular expression and proper parsing
from sys import argv, stderr, exit
if len(argv) < 3:
print >>stderr,"Usage:",argv[0]," <template.html> <target-doc-directory> [source XML document ... ]"
exit(5)
template = argv[1]
targetDir = argv[2]
f = open(template)
bp = f.read()
f.close()
doc = bp
import libxml2
import os.path
libxml2.substituteEntitiesDefault(True)
def asText(x):
d = libxml2.parseDoc(x)
return d.xpathCastNodeToString()
import re
wsRE = re.compile('\s+')
def trimWS(s):
s = wsRE.sub(' ', s)
if s and s[0] == ' ':
s = s[1:]
if s and s[-1] == ' ':
s = s[:-1]
return s
secRe = re.compile("<div id='(\w+)'>\n(.*?\n)</div>\n", re.DOTALL)
import codecs
def writeDoc(x, h):
f = open(x)
t = f.read()
f.close()
doc = bp
# Get the title
xd = libxml2.parseFile(x)
ctxt = xd.xpathNewContext()
ctxt.xpathRegisterNs('html', 'http://www.w3.org/1999/xhtml')
title = ctxt.xpathEvalExpression('string(/fvdoc//html:div[@id="message"])')
title = trimWS(title)
doc = doc.replace('<title></title>', '<title>' + title + '</title>')
for (sec, txt) in secRe.findall(t):
r = re.compile('<h2>' + sec + '</h2>\s*<div class="docbody">\s*()</div>', re.IGNORECASE)
idx = r.search(doc).start(1)
doc = doc[:idx] + txt + doc[idx:]
c = codecs.getdecoder('utf-8')
doc = c(doc)[0]
c = codecs.getencoder('iso-8859-1')
f = open(h, 'w')
f.write(c(doc, 'xmlcharrefreplace')[0])
f.close()
for f in argv[3:]:
sp = os.path.abspath(f)
if not(os.path.isfile(sp)):
continue
category = os.path.split(os.path.dirname(sp))[1]
filename = os.path.basename(sp)
if not(category):
continue
(name, ext) = os.path.splitext(filename)
if ext == '.xml':
writeDoc(sp, os.path.join(targetDir, category, name + '.html'))
else:
print >>stderr,"Ignoring",f

View file

@ -1,33 +0,0 @@
</div><!--main-->
<div class="centered">
<a name="startnavigation" id="startnavigation"></a>
<div class="navbarWrapper">
<div class="navbarContent">
<img class="borderTL" src="../images/borderTL.gif" alt="" width="14" height="14" />
<img class="borderTR" src="../images/borderTR.gif" alt="" width="14" height="14" />
<p>
<a href="../">Home</a> &middot;
<a href="../about.html">About</a> &middot;
<a href="../news/">News</a> &middot;
<a href="../docs/">Docs</a> &middot;
<a href="../terms.html">Terms</a>
</p>
<div class="roundedCornerSpacer">&nbsp;</div>
</div><!-- .content -->
<div class="bottomCorners">
<img class="borderBL" src="../images/borderBL.gif" alt="" width="14" height="14" />
<img class="borderBR" src="../images/borderBR.gif" alt="" width="14" height="14" />
</div><!-- .bottomCorners -->
</div><!-- .contentWrapper -->
</div><!-- .centered -->
<div class="centered">
<address>Copyright &copy; 2002-3 <a href="http://diveintomark.org/">Mark Pilgrim</a> and <a href="http://www.intertwingly.net/blog/">Sam Ruby</a></address>
</div>
</body>
</html>

View file

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Feed Validator Documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="icon" href="http://www.feedvalidator.org/favicon.ico" />
<link rel="shortcut icon" href="http://www.feedvalidator.org/favicon.ico" />
<style type="text/css" media="screen">@import "../css/common.css";
@import "../css/documentation.css";</style>
<script type="text/javascript"><!-- --></script>
</head>
<body>
<div id="logo">
<h1><a href="/"><span id="feed"><span id="f">F</span><span id="e1">E</span><span id="e2">E</span></span><span id="d">D</span> Validator</a></h1>
<p>Documentation</p>
<a class="skip" href="#startnavigation">Jump to navigation</a>
</div> <!--logo-->
<div id="main">
<h2>Tutorials</h2>
<ul>
<li><a href="howto/declare_namespaces.html">How do I declare namespaces in my RSS feed?</a></li>
<li><a href="howto/install_and_run.html">How do I install and run the Feed Validator?</a></li>
</ul>
<h2>Specifications</h2>
<ul>
<li><a href="http://www.atomenabled.org/developers/syndication/atom-format-spec.php">Atom 1.0</a></li>
<li><a href="rss1.html">RSS 1.0 specification</a></li>
<li><a href="rss2.html">RSS 2.0 specification</a></li>
</ul>

View file

@ -1,23 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> should not have text (all data is in attributes)</p>
</div>
<div id='explanation'>
<p>You have an old-style <code>link</code> in your Atom feed.</p>
</div>
<div id='solution'>
<p>In Atom 0.3, the format of <code>link</code> changed. Instead of simply containing an address of a page or resource, it now contains three attributes that describe the type of link, and the MIME type of the linked resource, and the address of the resource.</p>
<p>This was the format in Atom 0.2:</p>
<blockquote><code>&lt;link&gt;http://www.example.com/&lt;/link&gt;</code></blockquote>
<p>This is the new format in Atom 1.0 and later:</p>
<blockquote><code>&lt;link href="http://www.example.com/"/&gt;</code></blockquote>
<p>Note: this information only applies to Atom feeds (not RSS feeds).</p>
</div>
</div>
</fvdoc>

View file

@ -1,17 +0,0 @@
<!DOCTYPE fvdoc [
<!ENTITY nbsp "&#160;">
]>
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Feeds must specify XML Version 1.0</p>
</div>
<div id='explanation'>
<p>All RSS and Atom files must conform to the <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">XML 1.0</a> specification</p>
</div>
<div id='solution'>
<p>Replace the version string in the XML declaration with "1.0".&nbsp; The result should look something like this:</p>
<blockquote><p><code>&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;</code></p></blockquote>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Feeds must not contain SYSTEM entities</p>
</div>
<div id='explanation'>
<p>Your feed contains a <code>SYSTEM</code> entity. This is a security risk.</p>
</div>
<div id='solution'>
<p>Remove the <code>SYSTEM</code> entity. RSS feeds must be self-contained.</p>
</div>
</div>
</fvdoc>

View file

@ -1,15 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Duplicate alternate links with the same type and hreflang</p>
</div>
<div id='explanation'>
<p>atom:feed elements MUST NOT contain more than one atom:link
element with a rel attribute value of "alternate" that has the
same combination of type and hreflang attribute values.</p>
</div>
<div id='solution'>
<p>Remove one of the links.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> contains more than one <code>bar</code></p>
</div>
<div id='explanation'>
<p>Only one occurrence of the specified element is allowed in this context. For example, <code>channel</code> can only contain one <code>title</code> element.</p>
</div>
<div id='solution'>
<p>Delete the redundant element.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> values must not be duplicated within a feed</p>
</div>
<div id='explanation'>
<p>Only one occurrence of the specified value is allowed in the feed. For example, in RSS 2.0, <code>skipDay</code> elements can only contain one <code>day</code> element with a given value.</p>
</div>
<div id='solution'>
<p>Delete the redundant element.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>skipDays can not contain more than 7 day elements</p>
</div>
<div id='explanation'>
<p><a href="http://backend.userland.com/skipHoursDays#skipdays"><code>skipDays</code></a> can not contain more than 7 <code>day</code> elements.</p>
</div>
<div id='solution'>
<p>Remove the duplicate <code>days</code> elements.</p>
</div>
</div>
</fvdoc>

View file

@ -1,18 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>HTTP Error</p>
</div>
<div id='explanation'>
<p>Your feed couldn't be validated because there was a problem downloading
it from the web server. You should try to diagnose this using a web browser,
and make sure that the URL you supplied resolves to an accessible file.</p>
<p>This usually means that the URL was wrong, or that permissions on
the server don't allow us to fetch that file. The error shows the
message that the server sent, which may help.</p>
</div>
<div id='solution'>
<p>Make sure this URL can be downloaded with a browser, then try again.</p>
</div>
</div>
</fvdoc>

View file

@ -1,24 +0,0 @@
<!DOCTYPE fvdoc [
<!ENTITY ldquo "&#8220;">
<!ENTITY rdquo "&#8221;">
<!ENTITY rsquo "&#8217;">
]>
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>HTTP Protocol Error</p>
</div>
<div id='explanation'>
<p>The HTTP response from the server was invalid. This will prevent some
aggregators from downloading the feed at all.</p>
</div>
<div id='solution'>
<p>One common cause for this is WordPress&rsquo;s &ldquo;Last Modified&rdquo; header
(with a space, rather than a dash, separating the words).
See
<a href="http://wordpress.org/support/topic/13097#post-87665" title="RSS Feed Problems &#xab; WordPress Support">WordPress support</a>,
or upgrade to
<a href="http://wordpress.org/download/">a newer version</a>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,18 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>IO Error</p>
</div>
<div id='explanation'>
<p>Your feed couldn't be validated because there was a problem downloading
it from the web server. You should try to diagnose this using a web browser,
and make sure that the URL you supplied resolves to an accessible file.</p>
<p>One specific case that causes this is a server that claims the file
is compressed, but then serves an uncompressed file. You may need to contact
your host's administrators to resolve this problem.</p>
</div>
<div id='solution'>
<p>Make sure this URL can be downloaded with a browser, then try again.</p>
</div>
</div>
</fvdoc>

View file

@ -1,23 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Incorrect day of week: <code>foo</code></p>
</div>
<div id='explanation'>
<p>If included, day-of-week must be the day implied by the date
specification.</p>
<p>As an example, the following is an incorrect date:</p>
<blockquote><code>&lt;pubDate&gt;<b>Sat</b>, 31 Dec 1999 23:59:59 EST&lt;/pubDate&gt;</code></blockquote>
<p>The following is a corrected example:</p>
<blockquote><code>&lt;pubDate&gt;<b>Fri</b>, 31 Dec 1999 23:59:59 EST&lt;/pubDate&gt;</code></blockquote>
<p>This may be indicative of a more significant software error in the
formatting of dates that needs to be corrected.</p>
</div>
<div id='solution'>
<p>If it turns out that computing the correct day of week is impractical
using the software you have available, then
<a href="http://www.sendmail.org/rfc/0822.html#5">RFC 822</a> permits omitting
both the day of the week and the subsequent comma from the value.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for access:restriction: <code>foo</code></p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid access:restriction.</p>
</div>
<div id='solution'>
<p>Change the attribute value to either <code>allow</code> or <code>deny</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,24 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an email address</p>
</div>
<div id='explanation'>
<p>MUST conform to the "addr-spec" production in <a href="http://www.faqs.org/rfcs/rfc2822.html">RFC 2822</a></p>
</div>
<div id='solution'>
<p>Convert the email address to a valid form. Examples of valid email
addresses:</p>
<ul>
<li>joesmith@example.com</li>
<li>joesmith+nospamplease@nospam.example.com</li>
</ul>
<p>Note: addr-spec does not include a provision for a display-name. Use
atom:name instead. Examples of invalid email addresses:</p>
<ul>
<li>joesmith@example.com (Joe Smith)</li>
<li>Joe Smith &amp;lt;joesmith@example.com&amp;gt;</li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> attribute of <code>bar</code> must be 'true' or 'false'</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid boolean value.</p>
</div>
<div id='solution'>
<p>Change the attribute value to either <code>true</code> or <code>false</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,19 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be comma-separated integers</p>
</div>
<div id='explanation'>
<p>The value for this element must be a list of integers, separated by commas.</p>
</div>
<div id='solution'>
<p>Convert the value to a list of comma-separated integers. Examples
of valid comma-separated integers:</p>
<ul>
<li><samp>1</samp></li>
<li><samp>1,2,3</samp></li>
<li><samp>3, 5, 7</samp></li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,24 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must include an email address</p>
</div>
<div id='explanation'>
<p>Email addresses must conform to <a href="http://www.faqs.org/rfcs/rfc2822.html">
RFC 2822</a></p>
</div>
<div id='solution'>
<p>Convert the email address to a valid form. Examples of valid email
addresses:</p>
<ul>
<li>joesmith@example.com</li>
<li>joesmith@example.com (Joe Smith)</li>
<li>Joe Smith &amp;lt;joesmith@example.com&amp;gt;</li>
<li>joesmith.nospamplease@nospam.example.com</li>
</ul>
<p>Alternately, if the intent is to credit authorship without revealing
e-mail addresses, consider using the
<a href="http://www.rssboard.org/rss-profile#namespace-elements-dublin-creator">dc:creator</a> element instead.</p>
</div>
</div>
</fvdoc>

View file

@ -1,15 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> is not a valid mode</p>
</div>
<div id='explanation'>
<p>The <code>mode</code> attribute of a <code>content</code> element must be either <samp>"xml"</samp>, <samp>"escaped"</samp>, or <samp>"base64"</samp>.</p>
</div>
<div id='solution'>
<p>Use one of the acceptable values, or take out the attribute (it defaults to <samp>"xml"</samp>).</p>
<p>Like all attributes in XML, this attribute value is case sensitive.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid Coordinate</p>
</div>
<div id='explanation'>
<p>A point contains a single coordinate pair. The coordinate pair contains a latitude value and a longitude value in that order. The preferred serialization of this uses a space to separate the two values.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.georss.org/">GeoRSS documentation</a> for further details. You might find the <a href="http://www.georss.org/gml.html#examples">examples</a> particularly helpful.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid Coordinate</p>
</div>
<div id='explanation'>
<p>A line contains two or more coordinate pairs. Each pair contains a latitude value and a longitude value in that order. The preferred serialization of this uses a space to separate the two values. Pairs are separated from each other by a space.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.georss.org/">GeoRSS documentation</a> for further details. You might find the <a href="http://www.georss.org/gml.html#examples">examples</a> particularly helpful.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid counry code: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>The only acceptable values are ISO 3166 country codes..</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO documentation</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,18 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid Credit Role</p>
</div>
<div id='explanation'>
<p>Roles must be lower case. Additionally, if the <code>scheme</code> is not
specified as anything other than <code>urn:ebu</code>, roles must be selected
from the
<a href="http://www.ebu.ch/en/technical/metadata/specifications/role_codes.php">European Broadcasting Union Role Codes</a></p>
</div>
<div id='solution'>
<p>Change the role to be lower case, adjust the <code>scheme</code>, and/or
select a role from the
<a href="http://www.ebu.ch/en/technical/metadata/specifications/role_codes.php">European Broadcasting Union Role Codes</a></p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:currency</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Values must be in ISO 4217 currency code format.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.iso.org/iso/en/prods-services/popstds/currencycodeslist.html">ISO documentation</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, or Sunday</p>
</div>
<div id='explanation'>
<p><code>day</code> elements must be one of the following strings: "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", or "Sunday".</p>
</div>
<div id='solution'>
<p>Fix or remove any <code>day</code> elements that are invalid.</p>
</div>
</div>
</fvdoc>

View file

@ -1,15 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid duration: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Invalid duration.</p>
</div>
<div id='solution'>
<p>The tag can be formatted HH:MM:SS, H:MM:SS, MM:SS, or M:SS (H = hours, M = minutes, S = seconds)</p>
<p>An example of a valid Duration: <samp>7:40</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,16 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid character encoding: <i>foo</i></p>
</div>
<div id='explanation'>
<p>There is a problem with the character encoding specified.
This may be a typo, for example, <code>utf_8</code> rather
than <code>utf-8</code>, or may be an encoding that isn't registered.</p>
</div>
<div id='solution'>
<p>Replace the specified encoding with one of the
<a href="http://www.iana.org/assignments/character-sets" title="CHARACTER SETS">registered character set</a>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>&lt;expansionState&gt; is a comma-separated list of line numbers.</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid value for this element.</p>
</div>
<div id='solution'>
<p>Change the attribute value to a comma-separated list of line numbers.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>foo</code>: "<code>bar</code>"</p>
</div>
<div id='explanation'>
<p>Value is a floating point number.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>foo</code>: "<code>bar</code>"</p>
</div>
<div id='explanation'>
<p>Format is a floating point number optionally followed by a unit.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,16 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid form component name</p>
</div>
<div id='explanation'>
<p>The name MUST begin with a letter and
contain only these characters: the letters A to Z in either case,
numeric digits, colons (":"), hyphens ("-"), periods (".") and
underscores ("_").</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.rssboard.org/rss-draft-1#element-channel-textinput-name">documentation for the textInput name element</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,17 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a full URI</p>
</div>
<div id='explanation'>
<p>The specified value is not a full URI, or is mal-formed.</p>
</div>
<div id='solution'>
<p>If this is a link to a web page, make sure to include the "<code>http://</code>" at the beginning. If you've already done that, it's possible that the URI contains an invalid character. A complete list of acceptable characters can be found in <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.</p>
<p>If this is a mailing address, make sure to include the "<code>mailto:</code>" at the beginning.</p>
<p>The data in link elements <a href="../rss2.html#comments">must</a> begin win an <a href="http://www.iana.org/assignments/uri-schemes">IANA-registered</a> URI scheme</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:location</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Value should include street, city, state, postal code, and country, in that order.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#location">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:gender</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Acceptable values are "Male", "M", "Female", or "F".</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#gender">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be between 1 and 400</p>
</div>
<div id='explanation'>
<p><code><a href="../../docs/rss2.html#ltimagegtSubelementOfLtchannelgt">Image height</a></code> must be between 1 and 400.</p>
</div>
<div id='solution'>
<p>Resize your image manually, then specify the new height within range.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be between an integer 0 and 24</p>
</div>
<div id='explanation'>
<p><a href="http://backend.userland.com/skipHoursDays#skiphours"><code>hour</code> elements</a> must be an integer between 0 and 24.</p>
</div>
<div id='solution'>
<p>Remove any <code>hour</code> elements that are out of range.</p>
</div>
</div>
</fvdoc>

View file

@ -1,21 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>guid</code> must be a full URL, unless isPermaLink attribute is false</p>
</div>
<div id='explanation'>
<p>By default, the <code>guid</code> element specifies a permanent link for an item, the value must be a full URL (starting with "<code>&quot;http://&quot;</code>").</p>
</div>
<div id='solution'>
<p>If you are using the <code>guid</code> element as a permanent link, make sure the value is a full URL, including the "<code>http://</code>" at the beginning.</p>
<p>If you are using the <code>guid</code> element simply as a unique identifier (and not a link to the item), then the value can be whatever you want, but you must include the attribute <code>isPermaLink="false"</code> in the <code>guid</code> tag.</p>
<p>Both of these are valid <code>guid</code>s:</p>
<p><samp>&lt;guid&gt;http://www.example.com/archives/000054.html&lt;/guid&gt;</samp></p>
<p><samp>&lt;guid isPermaLink="false"&gt;article 54 at example.com&lt;/guid&gt;</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a valid IRI</p>
</div>
<div id='explanation'>
<p>The IRI contains an invalid character. A complete list of acceptable characters can be found in <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>.</p>
</div>
<div id='solution'>
<p>Replace the invalid characters with the proper escape sequence. For example, "{" and "}" characters should be replaced with "%7B" and "%7D" respectively.</p>
</div>
</div>
</fvdoc>

View file

@ -1,17 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an ISO-8601 date</p>
</div>
<div id='explanation'>
<p>Invalid date.</p>
</div>
<div id='solution'>
<p>The value specified must adhere to the
<a href="http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html">ISO 8601</a>
Date format. </p>
<p>An example of a valid ISO8601 Date: <samp>2002-10-02</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,17 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an ISO-8601 date-time</p>
</div>
<div id='explanation'>
<p>Invalid date-tie.</p>
</div>
<div id='solution'>
<p>The value specified must adhere to the
<a href="http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html">ISO 8601</a>
Date and time format. </p>
<p>An example of a valid ISO8601 Date-time: <samp>2002-10-02T10:00:00-05:00</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>foo</code>: "<code>bar</code>"</p>
</div>
<div id='explanation'>
<p>Format is an integer followed by an optional unit.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an integer</p>
</div>
<div id='explanation'>
<p>This value must be an integer greater than or equal to zero. It can not be negative, or a decimal, or a fraction, or a string, or blank.</p>
</div>
<div id='solution'>
<p>Make the specified value a non-negative integer.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> attribute of <code>bar</code> must be a positive integer</p>
</div>
<div id='explanation'>
<p>This attribute value must be an integer greater than zero. It can not be negative, or a decimal, or a fraction, or a string, or blank.</p>
</div>
<div id='solution'>
<p>Make the specified attribute value a positive integer.</p>
</div>
</div>
</fvdoc>

View file

@ -1,106 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> is not one of the predefined iTunes categories or sub-categories</p>
</div>
<div id='explanation'>
<p>itunes:category can only be populated using iTunes specific catgories or
sub-categories, as listed in the
<a href="http://www.apple.com/itunes/podcasts/techspecs.html#_Toc526931698">specification</a>.</p>
</div>
<div id='solution'>
<p>Change the attribute value to one of the following values:</p>
<ul>
<li>Arts</li>
<ul>
<li>Design</li>
<li>Fashion &amp; Beauty</li>
<li>Food</li>
<li>Literature</li>
<li>Performing Arts</li>
<li>Visual Arts</li>
</ul>
<li>Business</li>
<ul>
<li>Business News</li>
<li>Careers</li>
<li>Investing</li>
<li>Management &amp; Marketing</li>
<li>Shopping</li>
</ul>
<li>Comedy</li>
<li>Education</li>
<ul>
<li>Education Technology</li>
<li>Higher Education</li>
<li>K-12</li>
<li>Language Courses</li>
<li>Training</li>
</ul>
<li>Games &amp; Hobbies</li>
<ul>
<li>Automotive</li>
<li>Aviation</li>
<li>Hobbies</li>
<li>Other Games</li>
<li>Video Games</li>
</ul>
<li>Government &amp; Organizations</li>
<ul>
<li>Local</li>
<li>National</li>
<li>Non-Profit</li>
<li>Regional</li>
</ul>
<li>Health</li>
<ul>
<li>Alternative Health</li>
<li>Fitness &amp; Nutrition</li>
<li>Self-Help</li>
<li>Sexuality</li>
</ul>
<li>Kids &amp; Family</li>
<li>Music</li>
<li>News &amp; Politics</li>
<li>Religion &amp; Spirituality</li>
<ul>
<li>Buddhism</li>
<li>Christianity</li>
<li>Hinduism</li>
<li>Islam</li>
<li>Judaism</li>
<li>Other</li>
<li>Spirituality</li>
</ul>
<li>Science &amp; Medicine</li>
<ul>
<li>Medicine</li>
<li>Natural Sciences</li>
<li>Social Sciences</li>
</ul>
<li>Society &amp; Culture</li>
<ul>
<li>History</li>
<li>Personal Journals</li>
<li>Philosophy</li>
<li>Places &amp; Travel</li>
</ul>
<li>Sports &amp; Recreation</li>
<ul>
<li>Amateur</li>
<li>College &amp; High School</li>
<li>Outdoor</li>
<li>Professional</li>
</ul>
<li>Technology</li>
<ul>
<li>Gadgets</li>
<li>Podcasting</li>
<li>Software How-To</li>
<li>Tech News</li>
</ul>
<li>TV &amp; Film</li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:label</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Place each label in a separate &lt;label&gt; and &lt;/label&gt; tags.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#label">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,19 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an ISO-639 language code</p>
</div>
<div id='explanation'>
<p>The value specified must adhere to the <a href="http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes">W3C format for language codes</a>. </p>
<p>An example of a valid language code: <samp>en-us</samp></p>
</div>
<div id='solution'>
<p>Don't use the actual name of the language, like "English". Instead, use the 2- or 3-character language code, like "en" (ISO 639-1) or "eng" (ISO 639-2). (You can also specify a country code after it, like "en-us". This is optional, and the validator will ignore it.)</p>
<p>If you do include a country code, you need to separate the language code and the country code by a hyphen. "en-us" is valid; "en_us" is not.</p>
<p>The full set of language codes are defined by <a href="http://en.wikipedia.org/wiki/List_of_ISO_639_codes">ISO-639 language codes</a>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be between -90 and 90</p>
</div>
<div id='explanation'>
<p>The value for elements expressing latitude must be a number between -90 and 90.</p>
</div>
<div id='solution'>
<p>Use a number between -90 and 90 for the specified value.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a valid URI</p>
</div>
<div id='explanation'>
<p>The URI contains an invalid character. A complete list of acceptable characters can be found in <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.</p>
</div>
<div id='solution'>
<p>Replace the invalid characters with the proper escape sequence. For example, "{" and "}" characters should be replaced with "%7B" and "%7D" respectively.</p>
</div>
</div>
</fvdoc>

View file

@ -1,24 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid local parameter name: <i>foo</i></p>
</div>
<div id='explanation'>
<p>The specified parameter name is not one of the predefined local parameter names:</p>
<ul>
<li>searchTerms</li>
<li>count</li>
<li>startIndex</li>
<li>startPage</li>
<li>language</li>
<li>inputEncoding</li>
<li>outputEncoding</li>
</ul>
</div>
<div id='solution'>
<p>Either replace the parameter value with one listed in the
<a href="http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_1.1_parameters">OpenSearch 1.1 specification</a>, or use a
<a href="http://www.opensearch.org/Specifications/OpenSearch/1.1#Fully_qualified_parameter_names">fully qualified parameter name</a>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,35 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid local role: <i>foo</i></p>
</div>
<div id='explanation'>
<p>The specified role is not one of the permissable local role values:</p>
<dl><dt><code>"request"</code></dt>
<dd> Represents the search query that can be performed to retrieve the same set of search results.
</dd>
<dt><code>"example"</code></dt>
<dd> Represents a search query that can be performed to demonstrate the search engine.
</dd>
<dt><code>"related"</code></dt>
<dd> Represents a search query that can be performed to retrieve similar but different search results.
</dd>
<dt><code>"correction"</code></dt>
<dd> Represents a search query that can be performed to improve the result set, such as with a spelling correction.
</dd>
<dt><code>"subset"</code></dt>
<dd> Represents a search query that will narrow the current set of search results.
</dd>
<dt><code>"superset"</code></dt>
<dd> Represents a search query that will broaden the current set of search results.
</dd></dl>
</div>
<div id='solution'>
<p>Either replace the role value with one listed in the
<a href="http://www.opensearch.org/Specifications/OpenSearch/1.1#Local_role_values">OpenSearch 1.1 specification</a>, or use a
<a href="http://www.opensearch.org/Specifications/OpenSearch/1.1#Local_role_values">fully qualified role.</a>.
.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>foo</code>: "<code>bar</code>"</p>
</div>
<div id='explanation'>
<p>format is city and state/country, separated by a comma</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be between -180 and 180</p>
</div>
<div id='explanation'>
<p>The value for elements expressing longitude must be a number between -180 and 180.</p>
</div>
<div id='solution'>
<p>Use a number between -180 and 180 for the specified value.</p>
</div>
</div>
</fvdoc>

View file

@ -1,15 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> attribute of <code>bar</code> must be a valid MIME type</p>
</div>
<div id='explanation'>
<p>The attribute value specified is not a value MIME type.</p>
</div>
<div id='solution'>
<p>This attribute must be a valid MIME content type as defined by <a href="http://www.faqs.org/rfcs/rfc2045.html">RFC 2045</a>.</p>
<p>This is an example of a valid MIME type: <samp>text/html</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,25 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> is not a valid MIME type</p>
</div>
<div id='explanation'>
<p>This attribute is not a valid MIME type.</p>
</div>
<div id='solution'>
<p>Valid MIME types are specified in <a href="http://www.faqs.org/rfcs/rfc2046.html">RFC 2046</a>.</p>
<p>Examples of valid MIME types:</p>
<p><samp>application/xhtml+html</samp><br />
<samp>text/html</samp><br />
<samp>text/plain</samp></p>
<p>Examples of <em>invalid</em> MIME types:</p>
<p><samp>HTML</samp><br />
<samp>text</samp><br />
<samp>some stuff I threw together last night</samp></p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:marital_status</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Permissable values inclue "single", "divorced", "separated", "widowed", "married", and "in relationship".</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#marital_status">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,18 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid content expression: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid media:content expression value.</p>
</div>
<div id='solution'>
<p>Change the attribute to one of the following:</p>
<ul>
<li>full</li>
<li>nonstop</li>
<li>sample</li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,18 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid Media Hash</p>
</div>
<div id='explanation'>
<ul>
<li><samp>algo</samp> must be <samp>'md5'</samp> or <samp>'sha-1'</samp></li>
<li>value must be encoded as hex</li>
<li>value length must be 32 for md5 or 40 for sha-1</li>
</ul>
</div>
<div id='solution'>
<p>Convert the hash to a valid value, and/or use the <samp>algo</samp>
attribute to correctly indicate the hash algorithm used.</p>
</div>
</div>
</fvdoc>

View file

@ -1,20 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid content medium: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid media:content medium value.</p>
</div>
<div id='solution'>
<p>Change the attribute to one of the following:</p>
<ul>
<li>audio</li>
<li>document</li>
<li>executable</li>
<li>image</li>
<li>video</li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,41 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid Media Rating</p>
</div>
<div id='explanation'>
<ul>
<li><samp>scheme</samp> must be <samp>urn:simple</samp>,
<samp>urn:mpaa</samp>, <samp>urn:v-chip</samp>, <samp>urn:icra</samp>,
or a user defined URI. Default is <samp>urn:simple</samp></li>
<li>for one of the predefined schemes, the value must be lowercase, and be
one of the values listed below.</li>
</ul>
</div>
<div id='solution'>
<p>Select one of the schemes listed above, or use your own URI.</p>
<p>For one of the predefined schemes, the values must be as follows:</p>
<ul>
<li><b><samp>urn:simple</samp></b>:
<samp>adult</samp>, <samp>nonadult</samp></li>
<li><b><samp>urn:mpaa</samp></b>:
<samp>g</samp>, <samp>nc-17</samp>, <samp>pg</samp>,
<samp>pg-13</samp>, <samp>r</samp>, <samp>x</samp></li>
<li><b><samp>urn:v-chip</samp></b>:
<samp>14+</samp>, <samp>18+</samp>, <samp>c</samp>, <samp>c8</samp>,
<samp>g</samp>, <samp>pg</samp>, <samp>tv-14</samp>, <samp>tv-g</samp>,
<samp>tv-ma</samp>, <samp>tv-pg</samp>, <samp>tv-y</samp>, <samp>tv-y7</samp>,
<samp>tv-y7-fv</samp></li>
<li><b><samp>urn:icra</samp></b>: Internet Content Rating Association labels
consist of a <a href="http://www.icra.org/decode/">set of codes</a>
(please select from the values defined in 2005) formatted per the following
sample: <samp>r (cz 1 lz 1 mz 1 oz 1 vz 1)</samp></li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,14 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>media:restriction</code> must be 'all' or 'none'</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid media:restriction value.</p>
</div>
<div id='solution'>
<p>Change the value to either <code>all</code> or <code>none</code>.</p>
<p>Or specify a type of either <code>country</code> or <code>uri</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>relationship</code> must be 'allow' or 'disallow'</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid media:restriction relationship value.</p>
</div>
<div id='solution'>
<p>Change the attribute value to either <code>allow</code> or <code>disallow</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>type</code> must be 'country' or 'uri'</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid media:restriction type value.</p>
</div>
<div id='solution'>
<p>Change the attribute value to either <code>country</code> or <code>uri</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,14 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>type attribute must be "plain" or "html"</p>
</div>
<div id='explanation'>
<p>The specified attribute value is not a valid value for this element.</p>
</div>
<div id='solution'>
<p>Change the attribute value to either <code>plain</code> or <code>html</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,16 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>content</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>The <code>content</code> of a Robots META tag can only be:
<code>all</code>, <code>none</code>, <code>index</code>, <code>noindex</code>,
<code>follow</code>, or <code>nofollow</code>; or non-conflicting and
non-repeating combinations thereof, separated by commas.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.robotstxt.org/wc/meta-user.html">documentation for the Robots META tag</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>name</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Within a feed, the only expected value for <code>name</code> is <code>robots</code></p>
</div>
<div id='solution'>
<p>Consult the <a href="http://www.robotstxt.org/wc/meta-user.html">documentation for the Robots META tag</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,22 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be an NPT-time</p>
</div>
<div id='explanation'>
<p>The value specified must adhere to the
<a href="http://www.ietf.org/rfc/rfc2326.txt">RFC 2326</a>
ntp-time format. </p>
</div>
<div id='solution'>
<p>Convert the time into either a number of seconds, or a date of the format <samp>h:mm:ss.d</samp></p>
<p>Examples of valid ntp-times:</p>
<ul>
<li><samp>now</samp></li>
<li><samp>123.45</samp></li>
<li><samp>123:05:35.030</samp></li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,17 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> is in an invalid namespace</p>
</div>
<div id='explanation'>
<p>The feed defines a default namespace that this validator does not recognize.</p>
</div>
<div id='solution'>
<p>Atom does not allow arbitrary namespaces on the <code>feed</code> element. The correct namespace for Atom feeds is </p>
<p>http://www.w3.org/2005/Atom</p>
<p>For more information on Atom, see the <a href="http://intertwingly.net/wiki/pie/">Atom Project Wiki</a>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a non-negative integer</p>
</div>
<div id='explanation'>
<p>This value must be an integer greater than or equal to zero. It can not be negative, or a decimal, or a fraction, or a string, or blank.</p>
</div>
<div id='solution'>
<p>Make the specified value a positive integer, or zero.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>The "version" attribute for the opml element must be <code>1.0</code> or <code>1.1</code>.</p>
</div>
<div id='explanation'>
<p>The version of OPML is not supported by this validator.</p>
</div>
<div id='solution'>
<p>Change the version attribute to either <code>1.0</code> or <code>1.1</code>.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:payment_accepted</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>Acceptable values are "Cash", "Check", "Visa", "MasterCard", "AmericanExpress", "Discover" or "WireTransfer". If you accept more than one method, include multiple instances of the &lt;payment_accepted&gt; attribute for each acceptable method.</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#payment_accepted">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a percentage</p>
</div>
<div id='explanation'>
<p>This value must be an floating point number greater than or equal to zero and less than or equal to 100. It can not be negative, or a fraction, or a string, or blank.</p>
</div>
<div id='solution'>
<p>Make the specified value a non-negative floating point number less than 100.0.</p>
</div>
</div>
</fvdoc>

View file

@ -1,31 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>guid</code> must be a full URL, unless isPermaLink attribute is false</p>
</div>
<div id='explanation'>
<p>By default, the <code>guid</code> element specifies a permanent link for an
item, the value must be a full URL (for example, starting with
"<code>http://</code>").</p>
<p>URIs (such as <code>tag:</code> URIs), as opposed to URLs, only identify,
not locate, items, and are not suitable for permalinks.</p>
</div>
<div id='solution'>
<p>If you are using the <code>guid</code> element as a permanent link, make sure
the value is a full URL, that could be followed directly in a browser.</p>
<p>If you are using the <code>guid</code> element simply as a unique identifier
(and not a link to the item), then the value can be whatever you want, but you
must include the attribute <code>isPermaLink="false"</code> in the
<code>guid</code> tag.</p>
<p>These are valid <code>guid</code>s:</p>
<ul>
<li><samp>&lt;guid&gt;http://www.example.com/archives/000054.html&lt;/guid&gt;</samp></li>
<li><samp>&lt;guid isPermaLink="false"&gt;article 54 at example.com&lt;/guid&gt;</samp></li>
<li><samp>&lt;guid isPermaLink="false"&gt;tag:blogger.com,1999:blog-555&lt;/guid&gt;</samp></li>
</ul>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p><code>foo</code> must be a positive integer</p>
</div>
<div id='explanation'>
<p>This value must be an integer greater than zero. It can not be negative, or a decimal, or a fraction, or a string, or blank.</p>
</div>
<div id='solution'>
<p>Make the specified value a positive integer.</p>
</div>
</div>
</fvdoc>

View file

@ -1,13 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>Invalid value for <code>g:price_type</code>: "<code>foo</code>"</p>
</div>
<div id='explanation'>
<p>The type of pricing for the item. Acceptable values are "negotiable", or "starting".</p>
</div>
<div id='solution'>
<p>Consult the <a href="http://base.google.com/base/attribute_list.html#price_type">documentation for the attribute</a> for further details.</p>
</div>
</div>
</fvdoc>

View file

@ -1,24 +0,0 @@
<fvdoc>
<div xmlns='http://www.w3.org/1999/xhtml'>
<div id='message'>
<p>RDF Parsing Error</p>
</div>
<div id='explanation'>
<p>The feed uses an RDF format (RSS
<a href="http://www.purplepages.ie/RSS/netscape/rss0.90.html" title="My Netscape Network - RSS 0.90 Specification">0.90</a>,
<a href="http://web.resource.org/rss/1.0/" title="RDF Site Summary (RSS) 1.0">1.0</a>
or
<a href="http://inamidst.com/rss1.1/" title="RSS 1.1: RDF Site Summary (DRAFT)">1.1</a>),
but is not valid RDF/XML
(<a href="http://www.w3.org/TR/rdf-syntax-grammar/" title="RDF/XML Syntax Specification (Revised)">specification</a>).</p>
</div>
<div id='solution'>
<p>Make sure your feed matches the structure given in the feed specification,
including all <code>rdf:</code> attributes and elements. Check your feed
against the RDF/XML spec, and make sure that it is valid
RDF as well as well-formed XML. An RDF implementation with a tool such as
<a href="http://librdf.org/raptor/rapper.html" title="Raptor RDF Parser Toolkit - Raptor RDF parser utility">rapper</a>
can help to check for RDF validity.</p>
</div>
</div>
</fvdoc>

Some files were not shown because too many files have changed in this diff Show more