plain.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. from .. import ical
  26. from .. import config
  27. _folder = os.path.expanduser(config.get("support", "folder"))
  28. def calendars():
  29. """List available calendars paths."""
  30. calendars = []
  31. for folder in os.listdir(_folder):
  32. for cal in os.listdir(os.path.join(_folder, folder)):
  33. calendars.append(posixpath.join(folder, cal))
  34. return calendars
  35. def mkcalendar(name):
  36. """Write a new calendar called ``name``."""
  37. user, cal = name.split(posixpath.sep)
  38. if not os.path.exists(os.path.join(_folder, user)):
  39. os.makedirs(os.path.join(_folder, user))
  40. fd = open(os.path.join(_folder, user, cal), "w")
  41. fd.write(ical.write_calendar().encode(config.get("encoding", "stock")))
  42. def read(cal):
  43. """Read calendar ``cal``."""
  44. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  45. return open(path).read()
  46. def append(cal, vcalendar):
  47. """Append ``vcalendar`` to ``cal``."""
  48. old_calendar = unicode(read(cal), config.get("encoding", "stock"))
  49. old_tzs = [tz.tzid for tz in ical.timezones(old_calendar)]
  50. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  51. old_objects = []
  52. old_objects.extend([event.etag() for event in ical.events(old_calendar)])
  53. old_objects.extend([todo.etag() for todo in ical.todos(old_calendar)])
  54. objects = []
  55. objects.extend(ical.events(vcalendar))
  56. objects.extend(ical.todos(vcalendar))
  57. for tz in ical.timezones(vcalendar):
  58. if tz.tzid not in old_tzs:
  59. # TODO: Manage position, encoding and EOL
  60. fd = open(path)
  61. lines = [line for line in fd.readlines() if line]
  62. fd.close()
  63. for i,line in enumerate(tz.text.splitlines()):
  64. lines.insert(2+i, line.encode(config.get("encoding", "stock"))+"\n")
  65. fd = open(path, "w")
  66. fd.writelines(lines)
  67. fd.close()
  68. for obj in objects:
  69. if obj.etag() not in old_objects:
  70. # TODO: Manage position, encoding and EOL
  71. fd = open(path)
  72. lines = [line for line in fd.readlines() if line]
  73. fd.close()
  74. for line in obj.text.splitlines():
  75. lines.insert(-1, line.encode(config.get("encoding", "stock"))+"\n")
  76. fd = open(path, "w")
  77. fd.writelines(lines)
  78. fd.close()
  79. def remove(cal, etag):
  80. """Remove object named ``etag`` from ``cal``."""
  81. path = os.path.join(_folder, cal.replace(posixpath.sep, os.path.sep))
  82. cal = unicode(read(cal), config.get("encoding", "stock"))
  83. headers = ical.headers(cal)
  84. timezones = ical.timezones(cal)
  85. todos = [todo for todo in ical.todos(cal) if todo.etag() != etag]
  86. events = [event for event in ical.events(cal) if event.etag() != etag]
  87. fd = open(path, "w")
  88. fd.write(ical.write_calendar(headers, timezones, todos, events).encode(config.get("encoding", "stock")))
  89. fd.close()
  90. if config.get("support", "calendar"):
  91. user, cal = config.get("support", "calendar").split(posixpath.sep)
  92. if not os.path.exists(os.path.join(_folder, user, cal)):
  93. mkcalendar(config.get("support", "calendar"))