summaryrefslogtreecommitdiff
path: root/app/backend/import_cals.py
blob: f0b526278d7cc2aa8f4462abd12fd3143727b5b0 (plain)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import json
import os
import re
import time
import urllib2
import urlparse

from sqlalchemy import inspect

from rcal.db import Session
from rcal.model import Calendar, Category

BASEPATH = os.path.join(
    os.environ['PYTHONPATH'],
    '..',
    '..')

CONFIG = json.load(open(
    os.path.join(
        os.environ['PYTHONPATH'],
        'config',
        'reddit-import.json'),
    'r'))


def get_cal_list():
    cache_path = os.path.join(
        BASEPATH,
        CONFIG['cache'])
    if not os.path.exists(cache_path) or \
       int(time.time()) - int(os.path.getmtime(cache_path)) > \
       CONFIG['cache_time']:
        opener = urllib2.build_opener()
        opener.addheaders = [('User-Agent', CONFIG['user_agent'])]
        cal_list = json.loads(opener.open(CONFIG['reddit_url']).read())
        cal_list = cal_list['data']['content_md']
        with open(cache_path, 'w') as cache_file:
            cache_file.write(cal_list)
            cache_file.close()
    else:
        cal_list = open(cache_path, 'r').read()
    return cal_list


def update_calendar(cal, session):
    db_cal = Calendar.fetch(cal['uid'], session)

    if inspect(db_cal).pending:
        print 'Adding calendar %s (%s)' % (cal['name'], cal['uid'])
        db_cal.name = cal['name']
        db_cal.url = cal['url']
        db_cal.website = cal['website']
        db_cal.category = Category.fetch(cal['category'], session)

    if db_cal.name != cal['name']:
        print 'Updating calendar name: %s -> %s (%s)' % (
            db_cal.name, cal['name'], db_cal.uid)
        db_cal.name = cal['name']
    if db_cal.url != cal['url']:
        print 'Updating calendar url: %s -> %s (%s)' % (
            db_cal.url, cal['url'], db_cal.uid)
        db_cal.url = cal['url']
    if db_cal.website != cal['website']:
        print 'Updating calendar website: %s -> %s (%s)' % (
            db_cal.website, cal['website'], db_cal.uid)
        db_cal.website = cal['website']

    if 'category_mapping' in CONFIG and \
       cal['category'] in CONFIG['category_mapping']:
        cal['category'] = CONFIG['category_mapping'][cal['category']]

    # informational only
    if db_cal.category.name != cal['category']:
        print 'Calendar category changed: %s -> %s (%s, %s)' % (
            db_cal.category.name, cal['category'], db_cal.name, db_cal.uid)


def get_imported_calendars(cells, ical_markdown):
    imported_calendars = []
    for row in cells:
        row = [r for r in row if r.strip()]
        if len(row) == 5:
            markdown_match = re.match(ical_markdown, row[2])
            if markdown_match:
                ical_url = urlparse.urlparse(markdown_match.group(1))
                if ical_url.netloc == 'calendar.google.com':
                    ical_path = re.sub(
                        '^/?calendar/ical/', '', ical_url.path).split('/')
                    if len(ical_path) == 3:
                        imported_calendars.append({
                            'uid': ical_path[0],
                            'url': ical_url.geturl(),
                            'name': row[0],
                            'website': row[4].split()[0],
                            'category': row[1]
                        })
                    else:
                        print 'Unknown iCal URL format: %s' % (
                            ical_url.geturl())
                else:
                    print 'Unknown iCal URL format: %s' % (
                        ical_url.geturl())
    return imported_calendars


def main():
    session = Session.create()

    cal_list = get_cal_list()

    ical_markdown = re.compile(r'^\[iCal\]\((.*)\)$')
    cells = [row.split('|') for row in cal_list.split('\n')]

    imported_calendars = get_imported_calendars(cells, ical_markdown)
    imported_calendar_uids = [c['uid'] for c in imported_calendars]

    db_only_calendars = session.query(Calendar).filter(
        ~Calendar.uid.in_(imported_calendar_uids)).all()

    if len(db_only_calendars):
        print 'Local calendars not in remote source:'
        for cal in db_only_calendars:
            print '%s (%s)' % (cal.name, cal.uid)
        print

    for cal in imported_calendars:
        update_calendar(cal, session)

    session.commit()

if __name__ == '__main__':
    main()