<commit_before>"""
Parse iCal data to Events.
"""
# for UID generation
from random import randint
from datetime import datetime, timedelta, date
from dateutil.relativedelta import relativedelta
from dateutil.rrule import rrule, rruleset, rrulestr
from dateutil.tz import UTC, gettz

from icalendar import Calendar
from icalendar.prop import vDDDLists


# default query length (one week)
default_span = timedelta(days=7)


def now():
    """
    Get current time.

    :return: now as datetime with timezone
    """
    return datetime.now(UTC)


class Event:
    """
    Represents one event (occurrence in case of reoccurring events).
    """

    def __init__(self):
        """
        Create a new event occurrence.
        """
        self.uid = -1
        self.summary = None
        self.description = None
        self.start = None
        self.end = None
        self.all_day = True
        self.recurring = False

    def time_left(self, time=now()):
        """
        timedelta form now to event.

        :return: timedelta from now
        """
        return self.start - time

    def __lt__(self, other):
        """
        Events are sorted by start time by default.

        :param other: other event
        :return: True if start of this event is smaller than other
        """
        if not other or not isinstance(other, Event):
            raise ValueError('Only events can be compared with each other! Other is %s' % type(other))
        else:
            return self.start < other.start

    def __str__(self):
        n = now()

        # compute time delta description
        if not self.all_day:
            if self.end > n > self.start:
                # event is now
                delta = "now"
            elif self.start > n:
                # event is a future event
                if self.time_left().days > 0:
                    delta = "%s days left" % self.time_left().days
                else:
                    hours = self.time_left().seconds / (60 * 60)
                    delta = "%.1f hours left" % hours
            else:
                # event is over
                delta = "ended"
        else:
            if self.end > n > self.start:
                delta = "today"
            elif self.start > n:
                delta = "%s days left" % self.time_left().days
            else:
                delta = "ended"

        return "%s: %s (%s)" % (self.start, self.summary, delta)

    def copy_to(self, new_start=None, uid=None):
        """
        Create a new event equal to this with new start date.

        :param new_start: new start date
        :param uid: UID of new event
        :return: new event
        """
        if not new_start:
            new_start = self.start

        if not uid:
            uid = "%s_%d" % (self.uid, randint(0, 1000000))

        ne = Event()
        ne.summary = self.summary
        ne.description = self.description
        ne.start = new_start
        
        if self.end:
            duration = self.end - self.start
            ne.end = (new_start + duration)

        ne.all_day = self.all_day
        ne.recurring = self.recurring
        ne.uid = uid

        return ne


def create_event(component, tz=UTC):
    """
    Create an event from its iCal representation.

    :param component: iCal component
    :param tz: timezone for start and end times
    :return: event
    """

    event = Event()

    event.start = normalize(component.get('dtstart').dt, tz=tz)
    
    if component.get('dtend'):
        event.end = normalize(component.get('dtend').dt, tz=tz)
    elif component.get('duration'): # compute implicit end as start + duration
        event.end = event.start + component.get('duration').dt
    else: # compute implicit end as start + 0
        event.end = event.start
    
    try:
        event.summary = str(component.get('summary'))
    except UnicodeEncodeError as e:
        event.summary = str(component.get('summary').encode('utf-8'))
    try:
        event.description = str(component.get('description'))
    except UnicodeEncodeError as e:
        event.description = str(component.get('description').encode('utf-8'))
    event.all_day = type(component.get('dtstart').dt) is date
    if component.get('rrule'):
        event.recurring = True
    return event<commit_msg>Add a 'location' attribute to Event.<commit_after>"""
Parse iCal data to Events.
"""
# for UID generation
from random import randint
from datetime import datetime, timedelta, date
from dateutil.relativedelta import relativedelta
from dateutil.rrule import rrule, rruleset, rrulestr
from dateutil.tz import UTC, gettz

from icalendar import Calendar
from icalendar.prop import vDDDLists


# default query length (one week)
default_span = timedelta(days=7)


def now():
    """
    Get current time.

    :return: now as datetime with timezone
    """
    return datetime.now(UTC)


class Event:
    """
    Represents one event (occurrence in case of reoccurring events).
    """

    def __init__(self):
        """
        Create a new event occurrence.
        """
        self.uid = -1
        self.summary = None
        self.description = None
        self.start = None
        self.end = None
        self.all_day = True
        self.recurring = False
        self.location = None

    def time_left(self, time=now()):
        """
        timedelta form now to event.

        :return: timedelta from now
        """
        return self.start - time

    def __lt__(self, other):
        """
        Events are sorted by start time by default.

        :param other: other event
        :return: True if start of this event is smaller than other
        """
        if not other or not isinstance(other, Event):
            raise ValueError('Only events can be compared with each other! Other is %s' % type(other))
        else:
            return self.start < other.start

    def __str__(self):
        n = now()

        # compute time delta description
        if not self.all_day:
            if self.end > n > self.start:
                # event is now
                delta = "now"
            elif self.start > n:
                # event is a future event
                if self.time_left().days > 0:
                    delta = "%s days left" % self.time_left().days
                else:
                    hours = self.time_left().seconds / (60 * 60)
                    delta = "%.1f hours left" % hours
            else:
                # event is over
                delta = "ended"
        else:
            if self.end > n > self.start:
                delta = "today"
            elif self.start > n:
                delta = "%s days left" % self.time_left().days
            else:
                delta = "ended"

        return "%s: %s (%s)" % (self.start, self.summary, delta)

    def copy_to(self, new_start=None, uid=None):
        """
        Create a new event equal to this with new start date.

        :param new_start: new start date
        :param uid: UID of new event
        :return: new event
        """
        if not new_start:
            new_start = self.start

        if not uid:
            uid = "%s_%d" % (self.uid, randint(0, 1000000))

        ne = Event()
        ne.summary = self.summary
        ne.description = self.description
        ne.start = new_start
        
        if self.end:
            duration = self.end - self.start
            ne.end = (new_start + duration)

        ne.all_day = self.all_day
        ne.recurring = self.recurring
        ne.location = self.location
        ne.uid = uid

        return ne


def create_event(component, tz=UTC):
    """
    Create an event from its iCal representation.

    :param component: iCal component
    :param tz: timezone for start and end times
    :return: event
    """

    event = Event()

    event.start = normalize(component.get('dtstart').dt, tz=tz)
    
    if component.get('dtend'):
        event.end = normalize(component.get('dtend').dt, tz=tz)
    elif component.get('duration'): # compute implicit end as start + duration
        event.end = event.start + component.get('duration').dt
    else: # compute implicit end as start + 0
        event.end = event.start
    
    try:
        event.summary = str(component.get('summary'))
    except UnicodeEncodeError as e:
        event.summary = str(component.get('summary').encode('utf-8'))
    try:
        event.description = str(component.get('description'))
    except UnicodeEncodeError as e:
        event.description = str(component.get('description').encode('utf-8'))
    event.all_day = type(component.get('dtstart').dt) is date
    if component.get('rrule'):
        event.recurring = True
    try:
        event.location = str(component.get('location'))
    except UnicodeEncodeError as e:
        event.location = str(component.get('location').encode('utf-8'))
    return event
{'fraction_non_alphanumeric': 0.10219471018570625, 'fraction_numerical': 0.0043894203714124926, 'mean_word_length': 1.874797800064704, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '628248', 'n_tokens_mistral': 2570, 'n_tokens_neox': 2444, 'n_words': 785}