plain.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # -*- coding: utf-8 -*-
  2. #
  3. # This file is part of Radicale Server - Calendar Server
  4. # Copyright © 2008-2010 Guillaume Ayoub
  5. # Copyright © 2008 Nicolas Kandel
  6. # Copyright © 2008 Pascal Halter
  7. #
  8. # This library is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This library is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
  20. """
  21. Plain text storage.
  22. """
  23. import os
  24. import posixpath
  25. import codecs
  26. from radicale import config, ical
  27. _folder = os.path.expanduser(config.get("support", "folder"))
  28. def _open(path, mode="r"):
  29. return codecs.open(path, mode, config.get("encoding", "stock"))
  30. def calendars():
  31. """List available calendars paths."""
  32. calendars = []
  33. for folder in os.listdir(_folder):
  34. for cal in os.listdir(os.path.join(_folder, folder)):
  35. calendars.append(posixpath.join(folder, cal))
  36. return calendars
  37. def mkcalendar(name):
  38. """Write a new calendar called ``name``."""
  39. user, cal = name.split(posixpath.sep)
  40. if not os.path.exists(os.path.join(_folder, user)):
  41. os.makedirs(os.path.join(_folder, user))
  42. fd = _open(os.path.join(_folder, user, cal), "w")
  43. fd.write(ical.write_calendar())
  44. def read(cal):
  45. """Read calendar ``cal``."""
  46. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  47. return _open(path).read()
  48. def append(cal, vcalendar):
  49. """Append ``vcalendar`` to ``cal``."""
  50. old_calendar = read(cal)
  51. old_tzs = [tz.tzid for tz in ical.timezones(old_calendar)]
  52. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  53. old_objects = []
  54. old_objects.extend([event.etag() for event in ical.events(old_calendar)])
  55. old_objects.extend([todo.etag() for todo in ical.todos(old_calendar)])
  56. objects = []
  57. objects.extend(ical.events(vcalendar))
  58. objects.extend(ical.todos(vcalendar))
  59. for tz in ical.timezones(vcalendar):
  60. if tz.tzid not in old_tzs:
  61. # TODO: Manage position and EOL
  62. fd = _open(path)
  63. lines = [line for line in fd.readlines() if line]
  64. fd.close()
  65. for i,line in enumerate(tz.text.splitlines()):
  66. lines.insert(2 + i, line + "\n")
  67. fd = _open(path, "w")
  68. fd.writelines(lines)
  69. fd.close()
  70. for obj in objects:
  71. if obj.etag() not in old_objects:
  72. # TODO: Manage position and EOL
  73. fd = _open(path)
  74. lines = [line for line in fd.readlines() if line]
  75. fd.close()
  76. for line in obj.text.splitlines():
  77. lines.insert(-1, line + "\n")
  78. fd = _open(path, "w")
  79. fd.writelines(lines)
  80. fd.close()
  81. def remove(cal, etag):
  82. """Remove object named ``etag`` from ``cal``."""
  83. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  84. cal = read(cal)
  85. headers = ical.headers(cal)
  86. timezones = ical.timezones(cal)
  87. todos = [todo for todo in ical.todos(cal) if todo.etag() != etag]
  88. events = [event for event in ical.events(cal) if event.etag() != etag]
  89. fd = _open(path, "w")
  90. fd.write(ical.write_calendar(headers, timezones, todos, events))
  91. fd.close()
  92. if config.get("support", "calendar"):
  93. user, cal = config.get("support", "calendar").split(posixpath.sep)
  94. if not os.path.exists(os.path.join(_folder, user, cal)):
  95. mkcalendar(config.get("support", "calendar"))