__init__.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. # -*- coding: utf-8; indent-tabs-mode: nil; -*-
  2. #
  3. # This file is part of Radicale Server - Calendar Server
  4. # Copyright © 2008 The Radicale Team
  5. #
  6. # This library is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
  18. # TODO: Manage errors (see xmlutils)
  19. from twisted.web.resource import Resource
  20. from twisted.web import http
  21. import posixpath
  22. import config
  23. import support
  24. import acl
  25. import xmlutils
  26. import calendar
  27. _users = acl.users()
  28. _calendars = support.calendars()
  29. class CalendarResource(Resource):
  30. """
  31. Twisted resource for requests at calendar depth (/user/calendar)
  32. """
  33. isLeaf = True
  34. def __init__(self, user, cal):
  35. """
  36. Initialize resource creating a calendar object corresponding
  37. to the stocked calendar named user/cal
  38. """
  39. Resource.__init__(self)
  40. self.calendar = calendar.Calendar(user, cal)
  41. def render_DELETE(self, request):
  42. """
  43. Manage DELETE requests
  44. """
  45. obj = request.getHeader("if-match")
  46. answer = xmlutils.delete(obj, self.calendar, str(request.URLPath()))
  47. request.setResponseCode(http.NO_CONTENT)
  48. return answer
  49. def render_OPTIONS(self, request):
  50. """
  51. Manage OPTIONS requests
  52. """
  53. request.setHeader("Allow", "DELETE, OPTIONS, PROPFIND, PUT, REPORT")
  54. request.setHeader("DAV", "1, calendar-access")
  55. request.setResponseCode(http.OK)
  56. return ""
  57. def render_PROPFIND(self, request):
  58. """
  59. Manage PROPFIND requests
  60. """
  61. xmlRequest = request.content.read()
  62. answer = xmlutils.propfind(xmlRequest, self.calendar, str(request.URLPath()))
  63. request.setResponseCode(http.MULTI_STATUS)
  64. return answer
  65. def render_PUT(self, request):
  66. """
  67. Manage PUT requests
  68. """
  69. # TODO: Improve charset detection
  70. contentType = request.getHeader("content-type")
  71. if contentType and "charset=" in contentType:
  72. charset = contentType.split("charset=")[1].strip()
  73. else:
  74. charset = config.get("encoding", "request")
  75. icalRequest = unicode(request.content.read(), charset)
  76. obj = request.getHeader("if-match")
  77. xmlutils.put(icalRequest, self.calendar, str(request.URLPath()), obj)
  78. request.setResponseCode(http.CREATED)
  79. return ""
  80. def render_REPORT(self, request):
  81. """
  82. Manage REPORT requests
  83. """
  84. xmlRequest = request.content.read()
  85. answer = xmlutils.report(xmlRequest, self.calendar, str(request.URLPath()))
  86. request.setResponseCode(http.MULTI_STATUS)
  87. return answer
  88. class UserResource(Resource):
  89. """
  90. Twisted resource for requests at user depth (/user)
  91. """
  92. def __init__(self, user):
  93. """
  94. Initialize resource by connecting children requests to
  95. the user calendars resources
  96. """
  97. Resource.__init__(self)
  98. for cal in _calendars:
  99. if cal.startswith("%s%s"%(user, posixpath.sep)):
  100. calName = cal.split(posixpath.sep)[1]
  101. self.putChild(calName, CalendarResource(user, cal))
  102. def getChild(self, cal, request):
  103. """
  104. Get calendar resource if user exists
  105. """
  106. if cal in _calendars:
  107. return Resource.getChild(self, cal, request)
  108. else:
  109. return self
  110. class HttpResource(Resource):
  111. """
  112. Twisted resource for requests at root depth (/)
  113. """
  114. def __init__(self):
  115. """
  116. Initialize resource by connecting children requests to
  117. the users resources
  118. """
  119. Resource.__init__(self)
  120. for user in _users:
  121. self.putChild(user, UserResource(user))
  122. def getChild(self, user, request):
  123. """
  124. Get user resource if user exists
  125. """
  126. if user in _users:
  127. return Resource.getChild(self, user, request)
  128. else:
  129. return self