在GAE Python上托管动态iCal

时间:2014-04-11 21:09:47

标签: python google-app-engine icalendar

我正在计划一个保存事件数据库的应用程序。用户可以查询他们感兴趣的事件(基于地理位置,标签等),并获得动态iCal的链接以与他们的个人日历同步。将新事件添加到数据库以匹配其查询时,将更新其日历。

这应该使用python托管在GAE上。我已经找到了一个能够为iCal呈现内容的Python模块:icalendar

现在我的问题:如何设置Web服务器方面?我知道iCal不是通过http,而是通过webdav协议,但另一方面,webdav是http的扩展,具有用于向服务器执行写操作的额外功能,我不需要它用于我的只读日历,是吗?

问题1:我可以通过http://主持我的iCal,使用具有适当mime类型的webapp2而已吗?或者(某些)客户会不接受这个?

问题2:如果我需要webdav://协议,我从哪里开始?有webdav的模块,但它们更像文件服务器(参见herehere,看起来它们不再被维护),这完全不是我需要的。 webapp2或其他主流python web框架可以帮助我使用我的只读iCal吗? Webapp2帮助没有说一句关于webdav ...

感谢您提供任何建议!

维克

1 个答案:

答案 0 :(得分:0)

我在BaseHTTPRequestHandler之上实现了一个简单版本的iCalendar服务器。同样的想法可以与GAE一起使用。可以使用更复杂的内容渲染器,例如icalendar

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

PORT = 8000
DESC = "The long desciption of event. I've tried to keep it serious but at some point"


def limit_to_75_octets(inp):
    if len(inp) <= 73:
        return inp + "\r\n"

    out = ""
    while len(inp) > 73:
        out += inp[:73] + "\r\n"
        inp = " " + inp[73:]

    if len(inp) == 0:
        return out
    else:
        return out + inp + "\r\n"

def render_alarm():
    """creates an alarm 10 minutes before event start"""

    return ("BEGIN:VALARM\r\n" +
        "TRIGGER:-PT10M\r\n" +
        "ACTION:DISPLAY\r\n" +
        limit_to_75_octets("DESCRIPTION:Reminder: %s" % DESC) +
        "END:VALARM\r\n")

def render_event():
    """create and event
    uid: unique event id
    dtstamp: time when event was created
    dtstart: event start time
    dtend: event end time (all dates are in utc)
    """

    return ("BEGIN:VEVENT\r\n" +
        "UID:uid1@example.com\r\n" +
        "DTSTAMP:20141107T200200Z\r\n" +
        "DTSTART:20141109T153000Z\r\n" +
        "DTEND:20141109T163000Z\r\n" +
        limit_to_75_octets("SUMMARY:%s" % DESC) +
        render_alarm() +
        "END:VEVENT\r\n")

def render_calendar():
    return ("BEGIN:VCALENDAR\r\n" +
        "VERSION:2.0\r\n" +
        "PRODID:-//Example Corp.//CalDAV Server//EN\r\n" +
        render_event() +
        "END:VCALENDAR\r\n")


class SharedCalendarServer(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/calendar")
        self.end_headers()

        self.wfile.write(render_calendar())


if __name__ == "__main__":
    try:
        server = HTTPServer(("", PORT), SharedCalendarServer)
        print "Server running on", PORT
        server.serve_forever()

    except KeyboardInterrupt:
        print "Shutting down the web server."
        server.socket.close()