File: change_tz.py

package info (click to toggle)
python-vobject 0.9.8%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 608 kB
  • sloc: python: 3,562; sh: 7; makefile: 4
file content (93 lines) | stat: -rw-r--r-- 2,916 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""Translate an ics file's events to a different timezone."""

from datetime import datetime
from optparse import OptionParser

import pytz
from dateutil import tz

import vobject

version = "0.1"


def change_tz(cal, new_timezone, default, utc_only=False, utc_tz=vobject.icalendar.utc):
    """
    Change the timezone of the specified component.

    Args:
        cal (Component): the component to change
        new_timezone (tzinfo): the timezone to change to
        default (tzinfo): a timezone to assume if the dtstart or dtend in cal doesn't have an existing timezone
        utc_only (bool): only convert dates that are in utc
        utc_tz (tzinfo): the tzinfo to compare to for UTC when processing utc_only=True
    """

    for vevent in getattr(cal, 'vevent_list', []):
        start = getattr(vevent, 'dtstart', None)
        end = getattr(vevent, 'dtend', None)
        for node in (start, end):
            if node:
                dt = node.value
                if isinstance(dt, datetime) and (not utc_only or dt.tzinfo == utc_tz):
                    if dt.tzinfo is None:
                        dt = dt.replace(tzinfo=default)
                    node.value = dt.astimezone(new_timezone)


def show_timezones():
    for tz_string in pytz.all_timezones:
        print(tz_string)


def convert_events(utc_only, args):
    print("Converting {} events".format('only UTC' if utc_only else 'all'))
    ics_file = args[0]
    _tzone = args[1] if len(args) > 1 else 'UTC'

    print("... Reading {}".format(ics_file))
    cal = vobject.readOne(open(ics_file))
    change_tz(cal, new_timezone=tz.gettz(_tzone), default=tz.gettz('UTC'), utc_only=utc_only)

    out_name = "{}.converted".format(ics_file)
    print("... Writing {}".format(out_name))
    with open(out_name, 'wb') as out:
        cal.serialize(out)

    print("Done")


def main():
    options, args = get_options()

    if options.list:
        show_timezones()
    elif args:
        convert_events(utc_only=options.utc, args=args)


def get_options():
    # Configuration options
    usage = """usage: %prog [options] ics_file [timezone]"""
    parser = OptionParser(usage=usage, version=vobject.VERSION)
    parser.set_description("change_tz will convert the timezones in an ics file. ")

    parser.add_option("-u", "--only-utc", dest="utc", action="store_true",
                      default=False, help="Only change UTC events.")
    parser.add_option("-l", "--list", dest="list", action="store_true",
                      default=False, help="List available timezones")

    (cmdline_options, args) = parser.parse_args()
    if not (args or cmdline_options.list):
        print("error: too few arguments given")
        print(parser.format_help())
        return cmdline_options, False

    return cmdline_options, args


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("Aborted")