You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.4 KiB
181 lines
5.4 KiB
package de.kreth.clubhelperbackend.google.calendar;
|
|
|
|
import java.io.IOException;
|
|
import java.security.GeneralSecurityException;
|
|
import java.util.ArrayList;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.List;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.locks.Lock;
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
import com.google.api.client.util.DateTime;
|
|
import com.google.api.services.calendar.model.Calendar;
|
|
import com.google.api.services.calendar.model.CalendarList;
|
|
import com.google.api.services.calendar.model.CalendarListEntry;
|
|
import com.google.api.services.calendar.model.Event;
|
|
import com.google.api.services.calendar.model.EventAttendee;
|
|
|
|
import de.kreth.clubhelperbackend.google.GoogleBaseAdapter;
|
|
import de.kreth.clubhelperbackend.google.calendar.CalendarResource.CalendarKonfig;
|
|
|
|
public class CalendarAdapter extends GoogleBaseAdapter {
|
|
|
|
com.google.api.services.calendar.Calendar service;
|
|
private Lock lock = new ReentrantLock();
|
|
private CalendarResource res;
|
|
|
|
public CalendarAdapter() throws GeneralSecurityException, IOException {
|
|
super();
|
|
res = new CalendarResource();
|
|
|
|
}
|
|
|
|
@Override
|
|
protected void checkRefreshToken(String serverName) throws IOException {
|
|
try {
|
|
if (lock.tryLock(10, TimeUnit.SECONDS)) {
|
|
try {
|
|
super.checkRefreshToken(serverName);
|
|
if (service == null && credential != null) {
|
|
service = new com.google.api.services.calendar.Calendar.Builder(
|
|
HTTP_TRANSPORT, JSON_FACTORY, credential)
|
|
.setApplicationName(APPLICATION_NAME)
|
|
.build();
|
|
}
|
|
} finally {
|
|
lock.unlock();
|
|
}
|
|
}
|
|
} catch (InterruptedException e) {
|
|
if (log.isWarnEnabled()) {
|
|
log.warn("Lock interrupted", e);
|
|
}
|
|
}
|
|
if (service == null) {
|
|
throw new IllegalStateException(
|
|
"Calendar Service not instanciated!");
|
|
}
|
|
}
|
|
|
|
Calendar getCalendarBySummaryName(List<CalendarListEntry> items,
|
|
String calendarSummary) throws IOException {
|
|
|
|
String calendarId = null;
|
|
for (CalendarListEntry e : items) {
|
|
if (calendarSummary.equals(e.getSummary())) {
|
|
calendarId = e.getId();
|
|
break;
|
|
}
|
|
}
|
|
if (calendarId == null) {
|
|
throw new IllegalStateException(
|
|
"Calendar " + calendarSummary + " not found!");
|
|
}
|
|
|
|
return service.calendars().get(calendarId).execute();
|
|
}
|
|
|
|
public List<Event> getAllEvents(String serverName)
|
|
throws IOException, InterruptedException {
|
|
|
|
final List<Event> events = new ArrayList<>();
|
|
|
|
List<CalendarListEntry> items = getCalendarList(serverName);
|
|
final long oldest = getOldest();
|
|
|
|
List<CalendarKonfig> configs = res.getConfigs();
|
|
ExecutorService exec = Executors.newFixedThreadPool(configs.size());
|
|
for (CalendarKonfig c : configs) {
|
|
exec.execute(new FetchEventsRunner(items, c.getName(), events,
|
|
oldest, c.getColor()));
|
|
}
|
|
|
|
exec.shutdown();
|
|
try {
|
|
exec.awaitTermination(20, TimeUnit.SECONDS);
|
|
} catch (InterruptedException e) {
|
|
log.error("Thread terminated - event list may be incomplete.", e);
|
|
}
|
|
return events;
|
|
}
|
|
|
|
private long getOldest() {
|
|
GregorianCalendar oldestCal = new GregorianCalendar();
|
|
oldestCal.set(java.util.Calendar.DAY_OF_MONTH, 1);
|
|
oldestCal.set(java.util.Calendar.HOUR_OF_DAY, 0);
|
|
oldestCal.set(java.util.Calendar.MINUTE, 0);
|
|
oldestCal.add(java.util.Calendar.MONTH, -1);
|
|
oldestCal.add(java.util.Calendar.YEAR, -1);
|
|
oldestCal.add(java.util.Calendar.HOUR_OF_DAY, -1);
|
|
|
|
return oldestCal.getTimeInMillis();
|
|
}
|
|
|
|
List<CalendarListEntry> getCalendarList(String serverName)
|
|
throws IOException {
|
|
checkRefreshToken(serverName);
|
|
CalendarList calendarList;
|
|
try {
|
|
calendarList = service.calendarList().list().execute();
|
|
} catch (IOException e) {
|
|
if (log.isWarnEnabled()) {
|
|
log.warn("Error fetching Calendar List, trying token refresh",
|
|
e);
|
|
}
|
|
credential.refreshToken();
|
|
if (log.isInfoEnabled()) {
|
|
log.info("Successfully refreshed Google Security Token.");
|
|
}
|
|
calendarList = service.calendarList().list().execute();
|
|
}
|
|
return calendarList.getItems();
|
|
}
|
|
|
|
private final class FetchEventsRunner implements Runnable {
|
|
private final List<Event> events;
|
|
private final long oldest;
|
|
private String colorClass;
|
|
private List<CalendarListEntry> items;
|
|
private String summary;
|
|
|
|
private FetchEventsRunner(List<CalendarListEntry> items, String summary,
|
|
List<Event> events, long oldest, String colorClass) {
|
|
this.events = events;
|
|
this.oldest = oldest;
|
|
this.items = items;
|
|
this.summary = summary;
|
|
this.colorClass = colorClass;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
|
|
try {
|
|
log.debug("Fetching events of calendar \"{}\"", summary);
|
|
Calendar calendar = getCalendarBySummaryName(items, summary);
|
|
DateTime timeMin = new DateTime(oldest);
|
|
List<Event> eventItems = service.events().list(calendar.getId())
|
|
.setTimeMin(timeMin).execute().getItems();
|
|
eventItems.forEach(item -> item.set("colorClass", colorClass));
|
|
events.addAll(eventItems);
|
|
log.debug("Added {} Events for \"{}\"", eventItems.size(), summary);
|
|
|
|
} catch (IOException e) {
|
|
log.error("Unable to fetch Events from {}", summary, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Event createDefaultEvent(String summary) {
|
|
Event ev = new Event().setGuestsCanInviteOthers(false)
|
|
.setGuestsCanModify(false).setGuestsCanSeeOtherGuests(true)
|
|
.setSummary(summary);
|
|
List<EventAttendee> attendees = new ArrayList<>();
|
|
ev.setAttendees(attendees);
|
|
return ev;
|
|
}
|
|
|
|
}
|
|
|