ya3

ya3 -- yet another appointment application
Log | Files | Refs

utils.py (3217B)


      1 # Copyright 2021 Matthias Balk
      2 #
      3 # This file is part of ya3 (yet another appointment application).
      4 #
      5 # ya3 is free software: you can redistribute it and/or modify it under the
      6 # terms of the GNU Affero General Public License as published by the Free
      7 # Software Foundation, either version 3 of the License, or (at your option) any
      8 # later version.
      9 #
     10 # ya3 is distributed in the hope that it will be useful, but WITHOUT ANY
     11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12 # A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
     13 # details.
     14 #
     15 # You should have received a copy of the GNU Affero General Public License
     16 # along with ya3.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 from datetime import datetime
     19 
     20 import vobject
     21 from dateutil.tz import gettz
     22 
     23 import config
     24 
     25 
     26 def get_ya3_version():
     27     return '0.2'
     28 
     29 
     30 def parse2local(dt, force_datetime=False):
     31 
     32     if isinstance(dt, datetime):
     33         if dt.tzinfo is None:
     34             return datetime(dt.year, dt.month, dt.day,
     35                             dt.hour, dt.minute, dt.second,
     36                             tzinfo=gettz())
     37         return dt.astimezone(gettz())
     38 
     39     # date only
     40     else:
     41         if force_datetime:
     42             return datetime(dt.year, dt.month, dt.day,
     43                             0, 0, 0, tzinfo=gettz())
     44         else:
     45             return dt
     46 
     47 
     48 def normalize(event):
     49     if 'dtend' not in event.contents:
     50         event.add('dtend')
     51         if 'duration' in event.contents:
     52             event.dtend.value = event.dtstart.value + event.duration.value
     53         else:
     54             event.dtend.value = event.dtstart.value + config.DEFAULT_DURATION
     55 
     56     return event
     57 
     58 
     59 def get_events(icsfilenames, ignore_configured_range=False):
     60 
     61     def _is_in_range(event):
     62         if ignore_configured_range:
     63             return True
     64         start = parse2local(event.dtstart.value, force_datetime=True)
     65         end = parse2local(event.dtend.value, force_datetime=True)
     66         return (end >= datetime.now(gettz()) - config.MAX_AGE and
     67                 start < datetime.now(gettz()) + config.MAX_AHEAD)
     68 
     69     events = []
     70     for filename in icsfilenames:
     71         with open(filename) as f:
     72             for cal in vobject.readComponents(f):
     73                 events.extend(filter(_is_in_range,
     74                                      map(normalize, cal.vevent_list)))
     75 
     76     return sorted(events, key=lambda ev: parse2local(ev.dtstart.value,
     77                                                      force_datetime=True))
     78 
     79 
     80 def event2string(event):
     81     start = parse2local(event.dtstart.value)
     82     end = parse2local(event.dtend.value)
     83 
     84     try:
     85         location = " (" + event.location.value + ")"
     86     except AttributeError:
     87         location = ""
     88 
     89     if isinstance(start, datetime):
     90         return ('%s - %s %s%s' % (start.strftime('%Y-%m-%d %H:%M'),
     91                                   end.strftime('%H:%M'),
     92                                   event.summary.value,
     93                                   location))
     94 
     95     # date only
     96     else:
     97         return '{start}               {summary}{location}'.format(
     98                 start=start.strftime('%Y-%m-%d'),
     99                 summary=event.summary.value,
    100                 location=location)