PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/feedvalidator/opml.py

https://github.com/dh-benamor/restful-openerp
Python | 169 lines | 123 code | 42 blank | 4 comment | 27 complexity | c3918708f4fd7ccc4cc38969eb810817 MD5 | raw file
  1. """$Id$"""
  2. __author__ = "Sam Ruby <http://intertwingly.net/> and Mark Pilgrim <http://diveintomark.org/>"
  3. __version__ = "$Revision$"
  4. __copyright__ = "Copyright (c) 2002 Sam Ruby and Mark Pilgrim"
  5. from base import validatorBase
  6. from validators import *
  7. from logging import *
  8. from extension import extension_everywhere
  9. import re
  10. #
  11. # Outline Processor Markup Language element.
  12. #
  13. class opml(validatorBase, extension_everywhere):
  14. versionList = ['1.0', '1.1', '2.0']
  15. def validate(self):
  16. self.setFeedType(TYPE_OPML)
  17. if (None,'version') in self.attrs.getNames():
  18. if self.attrs[(None,'version')] not in opml.versionList:
  19. self.log(InvalidOPMLVersion({"parent":self.parent.name, "element":self.name, "value":self.attrs[(None,'version')]}))
  20. elif self.name != 'outlineDocument':
  21. self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"version"}))
  22. if 'head' not in self.children:
  23. self.log(MissingElement({"parent":self.name, "element":"head"}))
  24. if 'body' not in self.children:
  25. self.log(MissingElement({"parent":self.name, "element":"body"}))
  26. def getExpectedAttrNames(self):
  27. return [(None, u'version')]
  28. def do_head(self):
  29. return opmlHead()
  30. def do_body(self):
  31. return opmlBody()
  32. class opmlHead(validatorBase, extension_everywhere):
  33. def do_title(self):
  34. return safeHtml(), noduplicates()
  35. def do_dateCreated(self):
  36. return rfc822(), noduplicates()
  37. def do_dateModified(self):
  38. return rfc822(), noduplicates()
  39. def do_ownerName(self):
  40. return safeHtml(), noduplicates()
  41. def do_ownerEmail(self):
  42. return email(), noduplicates()
  43. def do_ownerId(self):
  44. return httpURL(), noduplicates()
  45. def do_expansionState(self):
  46. return commaSeparatedLines(), noduplicates()
  47. def do_vertScrollState(self):
  48. return positiveInteger(), nonblank(), noduplicates()
  49. def do_windowTop(self):
  50. return positiveInteger(), nonblank(), noduplicates()
  51. def do_windowLeft(self):
  52. return positiveInteger(), nonblank(), noduplicates()
  53. def do_windowBottom(self):
  54. return positiveInteger(), nonblank(), noduplicates()
  55. def do_windowRight(self):
  56. return positiveInteger(), nonblank(), noduplicates()
  57. class commaSeparatedLines(text):
  58. linenumbers_re=re.compile('^(\d+(,\s*\d+)*)?$')
  59. def validate(self):
  60. if not self.linenumbers_re.match(self.value):
  61. self.log(InvalidExpansionState({"parent":self.parent.name, "element":self.name, "value":self.value}))
  62. class opmlBody(validatorBase, extension_everywhere):
  63. def validate(self):
  64. if 'outline' not in self.children:
  65. self.log(MissingElement({"parent":self.name, "element":"outline"}))
  66. def do_outline(self):
  67. return opmlOutline()
  68. class opmlOutline(validatorBase, extension_everywhere):
  69. versionList = ['RSS', 'RSS1', 'RSS2', 'scriptingNews']
  70. def getExpectedAttrNames(self):
  71. return [
  72. (None, u'category'),
  73. (None, u'created'),
  74. (None, u'description'),
  75. (None, u'htmlUrl'),
  76. (None, u'isBreakpoint'),
  77. (None, u'isComment'),
  78. (None, u'language'),
  79. (None, u'text'),
  80. (None, u'title'),
  81. (None, u'type'),
  82. (None, u'url'),
  83. (None, u'version'),
  84. (None, u'xmlUrl'),
  85. ]
  86. def validate(self):
  87. if not (None,'text') in self.attrs.getNames():
  88. self.log(MissingAttribute({"parent":self.parent.name, "element":self.name, "attr":"text"}))
  89. if (None,'type') in self.attrs.getNames():
  90. if self.attrs[(None,'type')].lower() == 'rss':
  91. if not (None,'xmlUrl') in self.attrs.getNames():
  92. self.log(MissingXmlURL({"parent":self.parent.name, "element":self.name}))
  93. if not (None,'title') in self.attrs.getNames():
  94. self.log(MissingTitleAttr({"parent":self.parent.name, "element":self.name}))
  95. elif self.attrs[(None,'type')].lower() == 'link':
  96. if not (None,'url') in self.attrs.getNames():
  97. self.log(MissingUrlAttr({"parent":self.parent.name, "element":self.name}))
  98. else:
  99. opml = self.parent
  100. while opml and opml.name != 'opml':
  101. opml = opml.parent
  102. if opml and opml.attrs.get((None,'version')).startswith('1.'):
  103. self.log(InvalidOutlineType({"parent":self.parent.name, "element":self.name, "value":self.attrs[(None,'type')]}))
  104. if (None,'version') in self.attrs.getNames():
  105. if self.attrs[(None,'version')] not in opmlOutline.versionList:
  106. self.log(InvalidOutlineVersion({"parent":self.parent.name, "element":self.name, "value":self.attrs[(None,'version')]}))
  107. if len(self.attrs)>1 and not (None,u'type') in self.attrs.getNames():
  108. for name in u'description htmlUrl language title version xmlUrl'.split():
  109. if (None, name) in self.attrs.getNames():
  110. self.log(MissingOutlineType({"parent":self.parent.name, "element":self.name}))
  111. break
  112. self.validate_optional_attribute((None,'created'), rfc822)
  113. self.validate_optional_attribute((None,'description'), safeHtml)
  114. self.validate_optional_attribute((None,'htmlUrl'), rfc2396_full)
  115. self.validate_optional_attribute((None,'isBreakpoint'), truefalse)
  116. self.validate_optional_attribute((None,'isComment'), truefalse)
  117. self.validate_optional_attribute((None,'language'), iso639)
  118. self.validate_optional_attribute((None,'title'), safeHtml)
  119. self.validate_optional_attribute((None,'text'), safeHtml)
  120. self.validate_optional_attribute((None,'url'), rfc2396_full)
  121. def characters(self, string):
  122. if not self.value:
  123. if string.strip():
  124. self.log(UnexpectedText({"element":self.name,"parent":self.parent.name}))
  125. self.value = string
  126. def do_outline(self):
  127. return opmlOutline()