選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

131 行
4.0 KiB

  1. r"""
  2. hCalendar: A microformat for serializing iCalendar data
  3. (http://microformats.org/wiki/hcalendar)
  4. Here is a sample event in an iCalendar:
  5. BEGIN:VCALENDAR
  6. PRODID:-//XYZproduct//EN
  7. VERSION:2.0
  8. BEGIN:VEVENT
  9. URL:http://www.web2con.com/
  10. DTSTART:20051005
  11. DTEND:20051008
  12. SUMMARY:Web 2.0 Conference
  13. LOCATION:Argent Hotel\, San Francisco\, CA
  14. END:VEVENT
  15. END:VCALENDAR
  16. and an equivalent event in hCalendar format with various elements optimized appropriately.
  17. <span class="vevent">
  18. <a class="url" href="http://www.web2con.com/">
  19. <span class="summary">Web 2.0 Conference</span>:
  20. <abbr class="dtstart" title="2005-10-05">October 5</abbr>-
  21. <abbr class="dtend" title="2005-10-08">7</abbr>,
  22. at the <span class="location">Argent Hotel, San Francisco, CA</span>
  23. </a>
  24. </span>
  25. """
  26. import six
  27. from datetime import date, datetime, timedelta
  28. from .base import CRLF, registerBehavior
  29. from .icalendar import VCalendar2_0
  30. class HCalendar(VCalendar2_0):
  31. name = 'HCALENDAR'
  32. @classmethod
  33. def serialize(cls, obj, buf=None, lineLength=None, validate=True):
  34. """
  35. Serialize iCalendar to HTML using the hCalendar microformat (http://microformats.org/wiki/hcalendar)
  36. """
  37. outbuf = buf or six.StringIO()
  38. level = 0 # holds current indentation level
  39. tabwidth = 3
  40. def indent():
  41. return ' ' * level * tabwidth
  42. def out(s):
  43. outbuf.write(indent())
  44. outbuf.write(s)
  45. # not serializing optional vcalendar wrapper
  46. vevents = obj.vevent_list
  47. for event in vevents:
  48. out('<span class="vevent">' + CRLF)
  49. level += 1
  50. # URL
  51. url = event.getChildValue("url")
  52. if url:
  53. out('<a class="url" href="' + url + '">' + CRLF)
  54. level += 1
  55. # SUMMARY
  56. summary = event.getChildValue("summary")
  57. if summary:
  58. out('<span class="summary">' + summary + '</span>:' + CRLF)
  59. # DTSTART
  60. dtstart = event.getChildValue("dtstart")
  61. if dtstart:
  62. if type(dtstart) == date:
  63. timeformat = "%A, %B %e"
  64. machine = "%Y%m%d"
  65. elif type(dtstart) == datetime:
  66. timeformat = "%A, %B %e, %H:%M"
  67. machine = "%Y%m%dT%H%M%S%z"
  68. #TODO: Handle non-datetime formats?
  69. #TODO: Spec says we should handle when dtstart isn't included
  70. out('<abbr class="dtstart", title="{0!s}">{1!s}</abbr>\r\n'
  71. .format(dtstart.strftime(machine),
  72. dtstart.strftime(timeformat)))
  73. # DTEND
  74. dtend = event.getChildValue("dtend")
  75. if not dtend:
  76. duration = event.getChildValue("duration")
  77. if duration:
  78. dtend = duration + dtstart
  79. # TODO: If lacking dtend & duration?
  80. if dtend:
  81. human = dtend
  82. # TODO: Human readable part could be smarter, excluding repeated data
  83. if type(dtend) == date:
  84. human = dtend - timedelta(days=1)
  85. out('- <abbr class="dtend", title="{0!s}">{1!s}</abbr>\r\n'
  86. .format(dtend.strftime(machine),
  87. human.strftime(timeformat)))
  88. # LOCATION
  89. location = event.getChildValue("location")
  90. if location:
  91. out('at <span class="location">' + location + '</span>' + CRLF)
  92. description = event.getChildValue("description")
  93. if description:
  94. out('<div class="description">' + description + '</div>' + CRLF)
  95. if url:
  96. level -= 1
  97. out('</a>' + CRLF)
  98. level -= 1
  99. out('</span>' + CRLF) # close vevent
  100. return buf or outbuf.getvalue()
  101. registerBehavior(HCalendar)