Search in sources :

Example 1 with EventContainer

use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.

the class CalDavLoaderImpl method addEvent.

@Override
public void addEvent(CalDavEvent calDavEvent) {
    final CalendarRuntime calendarRuntime = EventStorage.getInstance().getEventCache().get(calDavEvent.getCalendarId());
    CalDavConfig config = calendarRuntime.getConfig();
    if (config == null) {
        log.error("cannot find config for calendar id: {}", calDavEvent.getCalendarId());
    }
    Sardine sardine = Util.getConnection(config);
    Calendar calendar = Util.createCalendar(calDavEvent, defaultTimeZone);
    try {
        final String fullIcsFile = config.getUrl() + "/" + calDavEvent.getFilename() + ".ics";
        if (calendarRuntime.getEventContainerByFilename(calDavEvent.getFilename()) != null) {
            log.debug("event will be updated: {}", fullIcsFile);
            try {
                sardine.delete(fullIcsFile);
            } catch (IOException e) {
                log.error("cannot remove old ics file: {}", fullIcsFile);
            }
        } else {
            log.debug("event is new: {}", fullIcsFile);
        }
        sardine.put(fullIcsFile, calendar.toString().getBytes("UTF-8"));
        EventContainer eventContainer = new EventContainer(calDavEvent.getCalendarId());
        eventContainer.setEventId(calDavEvent.getId());
        eventContainer.setFilename(Util.getFilename(calDavEvent.getFilename()));
        eventContainer.getEventList().add(calDavEvent);
        eventContainer.setLastChanged(calDavEvent.getLastChanged());
        this.addEventToMap(eventContainer, false);
    } catch (UnsupportedEncodingException e) {
        log.error("cannot write event", e);
    } catch (IOException e) {
        log.error("cannot write event", e);
    }
}
Also used : Sardine(com.github.sardine.Sardine) EventContainer(org.openhab.io.caldav.internal.EventStorage.EventContainer) Calendar(net.fortuna.ical4j.model.Calendar) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime)

Example 2 with EventContainer

use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.

the class CalDavLoaderImpl method addEventToMap.

public synchronized void addEventToMap(EventContainer eventContainer, boolean createTimer) {
    CalendarRuntime calendarRuntime = EventStorage.getInstance().getEventCache().get(eventContainer.getCalendarId());
    ConcurrentHashMap<String, EventContainer> eventContainerMap = calendarRuntime.getEventMap();
    if (eventContainerMap.containsKey(eventContainer.getEventId())) {
        EventContainer eventContainerOld = eventContainerMap.get(eventContainer.getEventId());
        // event is already in map
        if (eventContainer.getLastChanged().isAfter(eventContainerOld.getLastChanged())) {
            log.debug("event is already in event map and newer -> delete the old one, reschedule timer");
            // cancel old jobs
            for (String timerKey : eventContainerOld.getTimerMap()) {
                try {
                    this.scheduler.deleteJob(JobKey.jobKey(timerKey));
                } catch (SchedulerException e) {
                    log.error("cannot cancel event with job-id: " + timerKey, e);
                }
            }
            eventContainerOld.getTimerMap().clear();
            // override event
            eventContainerMap.put(eventContainer.getEventId(), eventContainer);
            for (EventNotifier notifier : eventListenerList) {
                for (CalDavEvent event : eventContainerOld.getEventList()) {
                    log.trace("notify listener... {}", notifier);
                    try {
                        notifier.eventRemoved(event);
                    } catch (Exception e) {
                        log.error("error while invoking listener", e);
                    }
                }
            }
            for (EventNotifier notifier : eventListenerList) {
                for (CalDavEvent event : eventContainer.getEventList()) {
                    log.trace("notify listener... {}", notifier);
                    try {
                        notifier.eventLoaded(event);
                    } catch (Exception e) {
                        log.error("error while invoking listener", e);
                    }
                }
            }
            if (createTimer) {
                int index = 0;
                for (CalDavEvent event : eventContainer.getEventList()) {
                    if (event.getEnd().isAfterNow()) {
                        try {
                            createJob(eventContainer, event, index);
                        } catch (SchedulerException e) {
                            log.error("cannot create jobs for event '{}': ", event.getShortName(), e.getMessage());
                        }
                    }
                    index++;
                }
            }
        } else {
            // event is already in map and not updated (eventContainerold and eventContainer have the same
            // "lastchanged" date) : we need to reschedule possible new events from recurrent events
            log.debug("event is already in map and not updated, we NEED to update eventlist and schedule new events jobs");
            ArrayList<CalDavEvent> eventsToAdd = new ArrayList<>();
            for (CalDavEvent event : eventContainer.getEventList()) {
                boolean eventAlreadyKnown = false;
                for (CalDavEvent oldevent : eventContainerOld.getEventList()) {
                    if (event.equals(oldevent)) {
                        eventAlreadyKnown = true;
                        log.trace("events match");
                    } else {
                        log.trace("eventsarenotequal : {} - {} - {} - {} - {}", event.getId(), event.getName(), event.getStart(), event.getEnd(), event.getLastChanged());
                        log.trace("eventsarenotequal : {} - {} - {} - {} - {}", oldevent.getId(), oldevent.getName(), oldevent.getStart(), oldevent.getEnd(), oldevent.getLastChanged());
                    }
                }
                if (!eventAlreadyKnown) {
                    eventsToAdd.add(event);
                }
            }
            // add only new events
            for (CalDavEvent event : eventsToAdd) {
                if (event.getEnd().isAfterNow()) {
                    eventContainerOld.getEventList().add(event);
                    for (EventNotifier notifier : eventListenerList) {
                        log.trace("notify listener... {}", notifier);
                        try {
                            notifier.eventLoaded(event);
                        } catch (Exception e) {
                            log.error("error while invoking listener", e);
                        }
                    }
                    if (createTimer) {
                        try {
                            log.trace("creating job for event {} ", event.getShortName());
                            createJob(eventContainerOld, event, eventContainerOld.getEventList().size() - 1);
                        // -1 because we already added the event to eventContainerOld
                        } catch (SchedulerException e) {
                            log.error("cannot create jobs for event '{}': ", event.getShortName(), e.getMessage());
                        }
                    }
                }
            }
            // update eventcontainer's calculateduntil
            eventContainerOld.setCalculatedUntil(eventContainer.getCalculatedUntil());
        }
    } else {
        // event is new
        eventContainerMap.put(eventContainer.getEventId(), eventContainer);
        log.trace("listeners for events: {}", eventListenerList.size());
        for (EventNotifier notifier : eventListenerList) {
            for (CalDavEvent event : eventContainer.getEventList()) {
                log.trace("notify listener... {}", notifier);
                try {
                    notifier.eventLoaded(event);
                } catch (Exception e) {
                    log.error("error while invoking listener", e);
                }
            }
        }
        if (createTimer) {
            int index = 0;
            for (CalDavEvent event : eventContainer.getEventList()) {
                if (event.getEnd().isAfterNow()) {
                    try {
                        createJob(eventContainer, event, index);
                    } catch (SchedulerException e) {
                        log.error("cannot create jobs for event: " + event.getShortName());
                    }
                }
                index++;
            }
        }
    }
}
Also used : SchedulerException(org.quartz.SchedulerException) EventContainer(org.openhab.io.caldav.internal.EventStorage.EventContainer) CalDavEvent(org.openhab.io.caldav.CalDavEvent) EventNotifier(org.openhab.io.caldav.EventNotifier) ArrayList(java.util.ArrayList) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime) ConfigurationException(org.osgi.service.cm.ConfigurationException) UnsupportedCharsetException(java.nio.charset.UnsupportedCharsetException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SchedulerException(org.quartz.SchedulerException) IOException(java.io.IOException)

Example 3 with EventContainer

use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.

the class EventReloaderJob method removeDeletedEvents.

private synchronized void removeDeletedEvents(String calendarKey, List<String> oldMap) {
    final CalendarRuntime eventRuntime = EventStorage.getInstance().getEventCache().get(calendarKey);
    for (String filename : oldMap) {
        EventContainer eventContainer = eventRuntime.getEventContainerByFilename(filename);
        if (eventContainer == null) {
            log.error("cannot find event container for filename: {}", filename);
            continue;
        }
        // cancel old jobs
        for (String jobId : eventContainer.getTimerMap()) {
            try {
                String group;
                if (jobId.startsWith(CalDavLoaderImpl.JOB_NAME_EVENT_START)) {
                    group = CalDavLoaderImpl.JOB_NAME_EVENT_START;
                } else if (jobId.startsWith(CalDavLoaderImpl.JOB_NAME_EVENT_END)) {
                    group = CalDavLoaderImpl.JOB_NAME_EVENT_END;
                } else {
                    throw new SchedulerException("unknown job id: " + jobId);
                }
                boolean deleteJob = CalDavLoaderImpl.instance.getScheduler().deleteJob(JobKey.jobKey(jobId, group));
                log.debug("old job ({}) deleted? {}", jobId, deleteJob);
            } catch (SchedulerException e) {
                log.error("cannot delete job '{}'", jobId);
            }
        }
        eventContainer.getTimerMap().clear();
        for (EventNotifier notifier : CalDavLoaderImpl.instance.getEventListenerList()) {
            for (CalDavEvent event : eventContainer.getEventList()) {
                try {
                    notifier.eventRemoved(event);
                } catch (Exception e) {
                    log.error("error while invoking listener", e);
                }
            }
        }
        ConcurrentHashMap<String, EventContainer> eventContainerMap = eventRuntime.getEventMap();
        if (eventContainer != null) {
            this.removeFromDisk(eventContainer);
            log.debug("remove deleted event: {}", eventContainer.getEventId());
            eventContainerMap.remove(eventContainer.getEventId());
        }
    }
}
Also used : SchedulerException(org.quartz.SchedulerException) EventContainer(org.openhab.io.caldav.internal.EventStorage.EventContainer) CalDavEvent(org.openhab.io.caldav.CalDavEvent) EventNotifier(org.openhab.io.caldav.EventNotifier) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime) ParserException(net.fortuna.ical4j.data.ParserException) JobExecutionException(org.quartz.JobExecutionException) SchedulerException(org.quartz.SchedulerException) IOException(java.io.IOException) SardineException(com.github.sardine.impl.SardineException)

Example 4 with EventContainer

use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.

the class EventReloaderJob method execute.

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    final String config = context.getJobDetail().getJobDataMap().getString(KEY_CONFIG);
    CalendarRuntime eventRuntime = EventStorage.getInstance().getEventCache().get(config);
    log.debug("running EventReloaderJob for config : {}", config);
    // reload cached events (if necessary)
    if (!cachedEventsLoaded.containsKey(config)) {
        try {
            log.debug("reload cached events for config: {}", eventRuntime.getConfig().getKey());
            for (File fileCalendarKeys : new File(CalDavLoaderImpl.CACHE_PATH).listFiles()) {
                if (!eventRuntime.getConfig().getKey().equals(Util.getFilename(fileCalendarKeys.getName()))) {
                    log.trace("not our config : {}", Util.getFilename(fileCalendarKeys.getName()));
                    continue;
                }
                log.trace("found our config : {}", Util.getFilename(fileCalendarKeys.getName()));
                final Collection<File> icsFiles = FileUtils.listFiles(fileCalendarKeys, new String[] { "ics" }, false);
                for (File icsFile : icsFiles) {
                    try {
                        FileInputStream fis = new FileInputStream(icsFile);
                        log.debug("loading events from file : {}", icsFile);
                        loadEvents(Util.getFilename(icsFile.getAbsolutePath()), new org.joda.time.DateTime(icsFile.lastModified()), fis, eventRuntime.getConfig(), new ArrayList<String>(), true);
                    } catch (IOException e) {
                        log.error("cannot load events for file: " + icsFile, e);
                    } catch (ParserException e) {
                        log.error("cannot load events for file: " + icsFile, e);
                    }
                }
                break;
            }
        } catch (Throwable e) {
            log.error("cannot load events", e);
        } finally {
            cachedEventsLoaded.put(config, true);
        }
    }
    try {
        log.debug("loading events for config: " + config);
        List<String> oldEventIds = new ArrayList<String>();
        for (EventContainer eventContainer : eventRuntime.getEventMap().values()) {
            oldEventIds.add(eventContainer.getFilename());
            log.debug("old eventcontainer -- id : {} -- filename : {} -- calcuntil : {} -- lastchanged : {} -- ishistoric : {}", eventContainer.getEventId(), eventContainer.getFilename(), eventContainer.getCalculatedUntil(), eventContainer.getLastChanged(), eventContainer.isHistoricEvent());
            if (log.isDebugEnabled()) {
                for (int i = 0; i < eventContainer.getEventList().size(); i++) {
                    CalDavEvent elem = eventContainer.getEventList().get(i);
                    log.debug("old eventlist contient l'evenement : {} -- deb : {} -- fin : {} -- lastchang {}", elem.getName(), elem.getStart(), elem.getEnd(), elem.getLastChanged());
                }
            }
        }
        loadEvents(eventRuntime, oldEventIds);
        // stop all events in oldMap
        removeDeletedEvents(config, oldEventIds);
        for (EventNotifier notifier : CalDavLoaderImpl.instance.getEventListenerList()) {
            try {
                notifier.calendarReloaded(config);
            } catch (Exception e) {
                log.error("error while invoking listener", e);
            }
        }
        // print All scheduled jobs :
        if (log.isDebugEnabled()) {
            log.debug("jobs scheduled : ");
            Scheduler scheduler = CalDavLoaderImpl.instance.getScheduler();
            for (String groupName : CalDavLoaderImpl.instance.getScheduler().getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                    String jobName = jobKey.getName();
                    String jobGroup = jobKey.getGroup();
                    // get job's trigger
                    List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                    Date nextFireTime = triggers.get(0).getNextFireTime();
                    log.debug("[job] : {} - [groupName] : {} - {}", jobName, jobGroup, nextFireTime);
                }
            }
        }
    } catch (SardineException e) {
        log.error("error while loading calendar entries: {} ({} - {} )", e.getMessage(), e.getStatusCode(), e.getResponsePhrase(), e);
        throw new JobExecutionException("error while loading calendar entries", e, false);
    } catch (Exception e) {
        log.error("error while loading calendar entries: {}", e.getMessage(), e);
        throw new JobExecutionException("error while loading calendar entries", e, false);
    }
}
Also used : Scheduler(org.quartz.Scheduler) ArrayList(java.util.ArrayList) JobKey(org.quartz.JobKey) SardineException(com.github.sardine.impl.SardineException) Trigger(org.quartz.Trigger) JobExecutionException(org.quartz.JobExecutionException) EventNotifier(org.openhab.io.caldav.EventNotifier) PropertyList(net.fortuna.ical4j.model.PropertyList) List(java.util.List) ArrayList(java.util.ArrayList) ComponentList(net.fortuna.ical4j.model.ComponentList) PeriodList(net.fortuna.ical4j.model.PeriodList) ParserException(net.fortuna.ical4j.data.ParserException) EventContainer(org.openhab.io.caldav.internal.EventStorage.EventContainer) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ParserException(net.fortuna.ical4j.data.ParserException) JobExecutionException(org.quartz.JobExecutionException) SchedulerException(org.quartz.SchedulerException) IOException(java.io.IOException) SardineException(com.github.sardine.impl.SardineException) Date(java.util.Date) CalDavEvent(org.openhab.io.caldav.CalDavEvent) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime) File(java.io.File)

Example 5 with EventContainer

use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.

the class EventReloaderJob method loadEvents.

public void loadEvents(String filename, org.joda.time.DateTime lastResourceChangeFS, final InputStream inputStream, final CalDavConfig config, final List<String> oldEventIds, boolean readFromFile) throws IOException, ParserException {
    CalendarBuilder builder = new CalendarBuilder();
    InputStreamReader is = new InputStreamReader(inputStream, config.getCharset());
    BufferedReader in = new BufferedReader(is, 50);
    final UnfoldingReader uin = new UnfoldingReader(in, 50, true);
    Calendar calendar = builder.build(uin);
    uin.close();
    // log.trace("calendar: {}", calendar);
    EventContainer eventContainer = new EventContainer(config.getKey());
    eventContainer.setFilename(filename);
    eventContainer.setLastChanged(lastResourceChangeFS);
    org.joda.time.DateTime loadFrom = org.joda.time.DateTime.now().minusMinutes(config.getHistoricLoadMinutes());
    org.joda.time.DateTime loadTo = org.joda.time.DateTime.now().plusMinutes(config.getPreloadMinutes());
    final ComponentList<CalendarComponent> vEventComponents = calendar.getComponents(Component.VEVENT);
    if (vEventComponents.size() == 0) {
        log.debug("could not find a VEVENT from calendar build, based on file {}", filename);
        // no events inside
        if (!readFromFile) {
            Util.storeToDisk(config.getKey(), filename, calendar);
        }
        return;
    }
    org.joda.time.DateTime lastModifedVEventOverAll = null;
    for (CalendarComponent comp : vEventComponents) {
        VEvent vEvent = (VEvent) comp;
        log.trace("loading event: " + vEvent.getUid().getValue() + ":" + vEvent.getSummary().getValue());
        // fallback, because 'LastModified' in VEvent is optional
        org.joda.time.DateTime lastModifedVEvent = lastResourceChangeFS;
        if (vEvent.getLastModified() != null) {
            lastModifedVEvent = new org.joda.time.DateTime(vEvent.getLastModified().getDateTime());
            log.trace("overriding lastmodified from file FS ({}) with event's last-modified property ({})", lastResourceChangeFS, lastModifedVEvent);
        }
        if (!config.isLastModifiedFileTimeStampValid()) {
            if (lastModifedVEventOverAll == null || lastModifedVEvent.isAfter(lastModifedVEventOverAll)) {
                lastModifedVEventOverAll = lastModifedVEvent;
            }
            if (eventContainer != null && !lastModifedVEvent.isBefore(eventContainer.getLastChanged())) {
                // to be created
                if (eventContainer.getCalculatedUntil() != null && vEventComponents.size() == 1 && eventContainer.getCalculatedUntil().isAfter(org.joda.time.DateTime.now().plusMinutes(config.getReloadMinutes()))) {
                    // the event is calculated as long as the next reload
                    // interval can handle this
                    log.trace("skipping resource processing {}, not changed", filename);
                    continue;
                }
                if (eventContainer.isHistoricEvent()) {
                    // no more upcoming events, do nothing
                    log.trace("skipping resource processing {}, not changed", filename);
                    continue;
                }
            }
        }
        Period period = new Period(new DateTime(loadFrom.toDate()), new DateTime(loadTo.toDate()));
        PeriodList periods = vEvent.calculateRecurrenceSet(period);
        periods = periods.normalise();
        String eventId = vEvent.getUid().getValue();
        final String eventName = vEvent.getSummary().getValue();
        // no more upcoming events
        if (periods.size() > 0) {
            if (vEvent.getConsumedTime(new net.fortuna.ical4j.model.Date(), new net.fortuna.ical4j.model.Date(org.joda.time.DateTime.now().plusYears(10).getMillis())).size() == 0) {
                log.trace("event will never be occur (historic): {}", eventName);
                eventContainer.setHistoricEvent(true);
            }
        }
        // expecting this is for every vEvent inside a calendar equals
        eventContainer.setEventId(eventId);
        eventContainer.setCalculatedUntil(loadTo);
        for (Period p : periods) {
            org.joda.time.DateTime start = getDateTime("start", p.getStart(), p.getRangeStart());
            org.joda.time.DateTime end = getDateTime("end", p.getEnd(), p.getRangeEnd());
            CalDavEvent event = new CalDavEvent(eventName, vEvent.getUid().getValue(), config.getKey(), start, end);
            event.setLastChanged(lastModifedVEvent);
            if (vEvent.getLocation() != null) {
                event.setLocation(vEvent.getLocation().getValue());
            }
            if (vEvent.getDescription() != null) {
                event.setContent(vEvent.getDescription().getValue());
            }
            event.getCategoryList().addAll(readCategory(vEvent));
            event.setFilename(filename);
            log.trace("adding event: " + event.getShortName());
            eventContainer.getEventList().add(event);
        }
    }
    if (lastModifedVEventOverAll != null && !config.isLastModifiedFileTimeStampValid()) {
        eventContainer.setLastChanged(lastModifedVEventOverAll);
        log.debug("changing eventcontainer last modified to {}", lastModifedVEventOverAll);
    }
    // if (!eventContainer.getEventList().isEmpty()) {
    CalDavLoaderImpl.instance.addEventToMap(eventContainer, true);
    if (!readFromFile) {
        Util.storeToDisk(config.getKey(), filename, calendar);
    }
// }
}
Also used : VEvent(net.fortuna.ical4j.model.component.VEvent) InputStreamReader(java.io.InputStreamReader) CalendarBuilder(net.fortuna.ical4j.data.CalendarBuilder) EventContainer(org.openhab.io.caldav.internal.EventStorage.EventContainer) CalendarComponent(net.fortuna.ical4j.model.component.CalendarComponent) UnfoldingReader(net.fortuna.ical4j.data.UnfoldingReader) Calendar(net.fortuna.ical4j.model.Calendar) Period(net.fortuna.ical4j.model.Period) PeriodList(net.fortuna.ical4j.model.PeriodList) DateTime(net.fortuna.ical4j.model.DateTime) LocalDateTime(org.joda.time.LocalDateTime) CalDavEvent(org.openhab.io.caldav.CalDavEvent) BufferedReader(java.io.BufferedReader) CalendarRuntime(org.openhab.io.caldav.internal.EventStorage.CalendarRuntime)

Aggregations

CalendarRuntime (org.openhab.io.caldav.internal.EventStorage.CalendarRuntime)8 EventContainer (org.openhab.io.caldav.internal.EventStorage.EventContainer)8 CalDavEvent (org.openhab.io.caldav.CalDavEvent)6 IOException (java.io.IOException)4 EventNotifier (org.openhab.io.caldav.EventNotifier)4 SardineException (com.github.sardine.impl.SardineException)3 ArrayList (java.util.ArrayList)3 ParserException (net.fortuna.ical4j.data.ParserException)3 JobExecutionException (org.quartz.JobExecutionException)3 SchedulerException (org.quartz.SchedulerException)3 Sardine (com.github.sardine.Sardine)2 File (java.io.File)2 FileInputStream (java.io.FileInputStream)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 Calendar (net.fortuna.ical4j.model.Calendar)2 DateTime (net.fortuna.ical4j.model.DateTime)2 PeriodList (net.fortuna.ical4j.model.PeriodList)2 LocalDateTime (org.joda.time.LocalDateTime)2 DavResource (com.github.sardine.DavResource)1 BufferedReader (java.io.BufferedReader)1