Search in sources :

Example 1 with ScheduleEntry

use of ws.nmathe.saber.core.schedule.ScheduleEntry in project Saber-Bot by notem.

the class CalendarConverter method importCalendar.

/**
 * Purges a schedule from entries and adds events (after conversion)
 * from the next 7 day span of a Google Calendar
 * @param address (String) valid address of calendar
 * @param channel (MessageChannel) channel to sync with
 * @param service connected calendar service with user credentials
 */
public void importCalendar(String address, TextChannel channel, Calendar service) {
    // sanity checks
    if (channel == null || address == null)
        return;
    if (!Main.getScheduleManager().isASchedule(channel.getId()))
        return;
    // query the google calendar address for the list of events
    Events events;
    try {
        ZonedDateTime min = ZonedDateTime.now();
        ZonedDateTime max = min.plusDays(Main.getScheduleManager().getSyncLength(channel.getId()));
        events = service.events().list(address).setTimeMin(new DateTime(min.format(EventRecurrence.RFC3339_FORMATTER))).setTimeMax(new DateTime(max.format(EventRecurrence.RFC3339_FORMATTER))).setOrderBy("startTime").setSingleEvents(true).setMaxResults(Main.getBotSettingsManager().getMaxEntries()).execute();
    } catch (Exception e) {
        Logging.exception(this.getClass(), e);
        return;
    }
    try // convert the list of Google Events into discord event entries
    {
        // send 'is typing' while the sync is in progress
        channel.sendTyping().queue();
        /* lock the schedule for syncing; schedule is unlocked in finally block */
        Main.getScheduleManager().lock(channel.getId());
        // change the zone to match the calendar
        // only if the zone has not been manually set for that schedule
        ZoneId zone = ZoneId.of(events.getTimeZone());
        Boolean syncZone = Main.getDBDriver().getScheduleCollection().find(eq("_id", channel.getId())).first().getBoolean("timezone_sync", false);
        if (syncZone) {
            Main.getScheduleManager().setTimeZone(channel.getId(), zone);
        }
        // a set of all unique (not child of a recurring event) events
        HashSet<String> uniqueEvents = new HashSet<>();
        // process events
        for (Event event : events.getItems()) {
            // continue to send 'is typing'
            channel.sendTyping().queue();
            // if the unique google event ID does not appear in the already processed events
            // convert the event and add it to the schedule
            String recurrenceId = event.getRecurringEventId();
            String googleId = recurrenceId == null ? event.getId() : recurrenceId;
            if (!uniqueEvents.contains(googleId)) {
                // declare and initialize event parameters
                ZonedDateTime start, end;
                String title;
                ArrayList<String> comments = new ArrayList<>();
                int repeat = 0;
                ZonedDateTime expire = null;
                String imageUrl = null;
                String thumbnailUrl = null;
                ZonedDateTime rsvpDeadline = null;
                String titleUrl = null;
                Map<String, Integer> rsvpLimits = new HashMap<>();
                if (event.getStart().getDateTime() == null) {
                    /* parse start and end dates for all day events */
                    start = ZonedDateTime.of(LocalDate.parse(event.getStart().getDate().toStringRfc3339()), LocalTime.MIN, zone);
                    end = ZonedDateTime.of(LocalDate.parse(event.getEnd().getDate().toStringRfc3339()), LocalTime.MIN, zone);
                } else {
                    /* parse start and end times for normal events */
                    start = ZonedDateTime.parse(event.getStart().getDateTime().toStringRfc3339(), EventRecurrence.RFC3339_FORMATTER).withZoneSameInstant(zone);
                    end = ZonedDateTime.parse(event.getEnd().getDateTime().toStringRfc3339(), EventRecurrence.RFC3339_FORMATTER).withZoneSameInstant(zone);
                }
                // get event title
                if (event.getSummary() == null)
                    title = "(No title)";
                else
                    title = event.getSummary();
                // process event description into event comments or other settings
                if (event.getDescription() != null) {
                    // process the description line by line
                    String description = HTMLStripper.cleanDescription(event.getDescription().replace("\n", "<br>"));
                    for (String comment : description.split("\n")) {
                        comment = comment.trim();
                        String lowerCase = comment.toLowerCase();
                        // image
                        if (lowerCase.startsWith("image:")) {
                            // split to limit:
                            String[] tmp = comment.split(":", 2);
                            if (tmp.length > 1) {
                                imageUrl = tmp[1].trim().replaceAll(" ", "");
                                if (!VerifyUtilities.verifyUrl(imageUrl))
                                    imageUrl = null;
                            }
                        } else // thumbnail
                        if (lowerCase.startsWith("thumbnail:")) {
                            String[] tmp = comment.split(":", 2);
                            if (tmp.length > 1) {
                                thumbnailUrl = tmp[1].trim().trim().replaceAll(" ", "");
                                if (!VerifyUtilities.verifyUrl(thumbnailUrl))
                                    thumbnailUrl = null;
                            }
                        } else // limit
                        if (lowerCase.startsWith("limit:")) {
                            // split to limit:
                            String[] tmp = comment.split(":", 2);
                            if (tmp.length > 1) {
                                // split into white space separated segments
                                String[] str = tmp[1].trim().split("[^\\S\n\r]+");
                                if (str.length >= 2) {
                                    // rebuild the rsvp group name
                                    StringBuilder name = new StringBuilder();
                                    for (int i = 0; i < str.length - 1; i++) {
                                        name.append(str[i]);
                                        if (i != str.length - 2)
                                            name.append(" ");
                                    }
                                    // parse the limit
                                    Integer limit = -1;
                                    if (VerifyUtilities.verifyInteger(str[str.length - 1]))
                                        limit = Integer.parseInt(str[str.length - 1]);
                                    rsvpLimits.put(name.toString(), limit);
                                }
                            }
                        } else // title url
                        if (lowerCase.startsWith("url:")) {
                            String[] tmp = comment.split(":", 2);
                            if (tmp.length > 1 && VerifyUtilities.verifyUrl(tmp[1].trim().replaceAll(" ", "")))
                                titleUrl = tmp[1].trim().replaceAll(" ", "");
                        } else // deadline
                        if (lowerCase.startsWith("deadline:")) {
                            String tmp = lowerCase.replace("deadline:", "").trim().replaceAll(" ", "");
                            if (VerifyUtilities.verifyDate(tmp))
                                rsvpDeadline = ParsingUtilities.parseDate(tmp, zone);
                        } else // plaintext comment
                        if (!comment.trim().isEmpty()) {
                            comments.add(comment);
                        }
                    }
                }
                // get the event recurrence information
                List<String> recurrence = event.getRecurrence();
                if (recurrenceId != null)
                    recurrence = service.events().get(address, recurrenceId).execute().getRecurrence();
                // parse the event recurrence information
                if (recurrence != null) {
                    // determine the start date
                    ZonedDateTime dtStart = // if orig is null, use start
                    event.getOriginalStartTime() == null ? // if orig is null, use start
                    start : (event.getOriginalStartTime().getDateTime() == null ? start : ZonedDateTime.parse(event.getOriginalStartTime().getDateTime().toStringRfc3339(), EventRecurrence.RFC3339_FORMATTER).withZoneSameInstant(zone));
                    EventRecurrence eventRecurrence = new EventRecurrence(recurrence, dtStart);
                    expire = eventRecurrence.getExpire();
                    repeat = eventRecurrence.getRepeat();
                }
                // if the google event already exists as a saber event on the schedule, update it
                // otherwise add as a new saber event
                Document doc = Main.getDBDriver().getEventCollection().find(and(eq("channelId", channel.getId()), eq("googleId", googleId))).first();
                // should the event be flagged as already started?
                boolean hasStarted = start.isBefore(ZonedDateTime.now());
                if (doc != null && (new ScheduleEntry(doc)).getMessageObject() != null) {
                    /* update an existing event */
                    ScheduleEntry se = (new ScheduleEntry(doc)).setTitle(title).setStart(start).setEnd(end).setRepeat(repeat).setGoogleId(googleId).setExpire(expire).setStarted(hasStarted).setComments(comments).setLocation(event.getLocation());
                    // set special attributes if not null
                    if (titleUrl != null)
                        se.setTitleUrl(titleUrl);
                    if (imageUrl != null)
                        se.setImageUrl(imageUrl);
                    if (thumbnailUrl != null)
                        se.setThumbnailUrl(thumbnailUrl);
                    if (rsvpDeadline != null)
                        se.setRsvpDeadline(rsvpDeadline);
                    if (rsvpLimits.keySet().size() > 0)
                        se.setRsvpLimits(rsvpLimits);
                    // update event reminders using schedule default settings
                    se.reloadReminders(Main.getScheduleManager().getReminders(se.getChannelId())).reloadEndReminders(Main.getScheduleManager().getEndReminders(se.getChannelId())).regenerateAnnouncementOverrides();
                    Main.getEntryManager().updateEntry(se, false);
                } else {
                    /* create a new event */
                    ScheduleEntry se = (new ScheduleEntry(channel, title, start, end)).setTitleUrl(titleUrl != null ? titleUrl : event.getHtmlLink()).setRepeat(repeat).setGoogleId(googleId).setExpire(expire).setStarted(hasStarted).setComments(comments).setLocation(event.getLocation());
                    // set special attributes if not null
                    if (imageUrl != null)
                        se.setImageUrl(imageUrl);
                    if (thumbnailUrl != null)
                        se.setThumbnailUrl(thumbnailUrl);
                    if (rsvpDeadline != null)
                        se.setRsvpDeadline(rsvpDeadline);
                    if (rsvpLimits.keySet().size() > 0)
                        se.setRsvpLimits(rsvpLimits);
                    Main.getEntryManager().newEntry(se, false);
                }
                // add to google ID to unique event mapping
                uniqueEvents.add(recurrenceId == null ? event.getId() : recurrenceId);
            }
        }
        // purge channel of all entries on schedule that aren't in uniqueEvents
        Bson query = and(eq("channelId", channel.getId()), nin("googleId", uniqueEvents));
        Main.getDBDriver().getEventCollection().find(query).forEach((Consumer<? super Document>) document -> {
            ScheduleEntry entry = Main.getEntryManager().getEntry((Integer) document.get("_id"));
            Message msg = entry.getMessageObject();
            if (msg == null)
                return;
            Main.getEntryManager().removeEntry((Integer) document.get("_id"));
            MessageUtilities.deleteMsg(msg, null);
        });
        // set channel topic
        JDA jda = Main.getShardManager().getJDA(channel.getGuild().getId());
        String calLink = "https://calendar.google.com/calendar/embed?src=" + address;
        boolean hasPerms = channel.getGuild().getMember(jda.getSelfUser()).hasPermission(channel, Permission.MANAGE_CHANNEL);
        if (hasPerms)
            channel.getManagerUpdatable().getTopicField().setValue(calLink).update().queue();
    } catch (Exception e) {
        Logging.exception(this.getClass(), e);
    } finally {
        // syncing done, unlock the channel
        Main.getScheduleManager().unlock(channel.getId());
    }
    // auto-sort
    EntryManager.autoSort(true, channel.getId());
}
Also used : Document(org.bson.Document) java.util(java.util) TextChannel(net.dv8tion.jda.core.entities.TextChannel) EventRecurrence(ws.nmathe.saber.core.schedule.EventRecurrence) Message(net.dv8tion.jda.core.entities.Message) Bson(org.bson.conversions.Bson) Filters(com.mongodb.client.model.Filters) DateTime(com.google.api.client.util.DateTime) java.time(java.time) Matcher(java.util.regex.Matcher) Permission(net.dv8tion.jda.core.Permission) JDA(net.dv8tion.jda.core.JDA) Calendar(com.google.api.services.calendar.Calendar) VerifyUtilities(ws.nmathe.saber.utils.VerifyUtilities) Logging(ws.nmathe.saber.utils.Logging) IOException(java.io.IOException) ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) Consumer(java.util.function.Consumer) com.google.api.services.calendar.model(com.google.api.services.calendar.model) DateTimeFormatter(java.time.format.DateTimeFormatter) EntryManager(ws.nmathe.saber.core.schedule.EntryManager) MessageUtilities(ws.nmathe.saber.utils.MessageUtilities) Main(ws.nmathe.saber.Main) Pattern(java.util.regex.Pattern) ParsingUtilities(ws.nmathe.saber.utils.ParsingUtilities) Message(net.dv8tion.jda.core.entities.Message) JDA(net.dv8tion.jda.core.JDA) Document(org.bson.Document) DateTime(com.google.api.client.util.DateTime) Bson(org.bson.conversions.Bson) EventRecurrence(ws.nmathe.saber.core.schedule.EventRecurrence) ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) IOException(java.io.IOException)

Example 2 with ScheduleEntry

use of ws.nmathe.saber.core.schedule.ScheduleEntry in project Saber-Bot by notem.

the class AnnouncementsCommand method verify.

@Override
public String verify(String prefix, String[] args, MessageReceivedEvent event) {
    String head = prefix + this.name();
    int index = 0;
    // length checks
    if (args.length < 1) {
        return "That's not enough arguments!\n" + "Use ``" + head + " <ID> [<add|remove> <args>]``";
    }
    // check for a valid entry ID
    if (!VerifyUtilities.verifyEntryID(args[index])) {
        return "``" + args[index] + "`` is not a valid entry ID!";
    }
    // check to see if event with the provided ID exists for the guild
    Integer Id = ParsingUtilities.encodeIDToInt(args[index]);
    ScheduleEntry entry = Main.getEntryManager().getEntryFromGuild(Id, event.getGuild().getId());
    if (entry == null) {
        return "I could not find an entry with that ID!";
    }
    // next argument is optional
    index++;
    if (args.length > 2) {
        String verify;
        if (args.length - index < 1) {
            return "That's not the right number of arguments for **" + args[index - 1] + "**!\n" + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [add|remove] [#target] [time] [message]``";
        }
        switch(args[index++].toLowerCase()) {
            case "a":
            case "add":
                verify = VerifyUtilities.verifyAnnouncementAdd(args, index, head, event);
                if (!verify.isEmpty())
                    return verify;
                break;
            case "r":
            case "remove":
                verify = VerifyUtilities.verifyAnnouncementRemove(args, index, head, entry);
                if (!verify.isEmpty())
                    return verify;
                break;
            case "qs":
            case "quiet-start":
            case "qe":
            case "quiet-end":
            case "qr":
            case "quiet-remind":
            case "quiet-all":
            case "qa":
                break;
            default:
                return "**" + args[index] + "** is not a valid option!\n" + "You should use either *add* or *remove*!";
        }
    }
    // return valid
    return "";
}
Also used : ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry)

Example 3 with ScheduleEntry

use of ws.nmathe.saber.core.schedule.ScheduleEntry in project Saber-Bot by notem.

the class EventsCommand method action.

@Override
public void action(String prefix, String[] args, MessageReceivedEvent event) {
    // process any optional channel arguments
    List<String> channelIds = new ArrayList<>();
    for (String arg : args) {
        channelIds.add(arg.replaceAll("[^\\d]", ""));
    }
    Guild guild = event.getGuild();
    List<String> scheduleIds = Main.getScheduleManager().getSchedulesForGuild(guild.getId());
    if (!channelIds.isEmpty()) {
        // filter the list of schedules
        scheduleIds = scheduleIds.stream().filter(channelIds::contains).collect(Collectors.toList());
    }
    // build the embed body content
    Member caller = event.getGuild().getMember(event.getAuthor());
    StringBuilder content = new StringBuilder();
    String title = "Events on " + guild.getName(), footer = "(events list continued on next page)";
    MessageEmbed embed;
    // total number of events
    int count = 0;
    for (String sId : scheduleIds) {
        // only show users events that are on schedules they can view
        TextChannel sChannel = event.getGuild().getTextChannelById(sId);
        List<Permission> permissions = sChannel != null ? caller.getPermissions(sChannel) : new ArrayList();
        if (sChannel != null && permissions != null && permissions.contains(Permission.MESSAGE_READ)) {
            // for each schedule, generate a list of events scheduled
            Collection<ScheduleEntry> entries = Main.getEntryManager().getEntriesFromChannel(sId);
            if (!entries.isEmpty()) {
                if (content.length() > 1700) {
                    // build embed and message
                    embed = new EmbedBuilder().setFooter(footer, null).setTitle(title).setDescription(content.toString()).build();
                    // build message
                    Message message = new MessageBuilder().setEmbed(embed).build();
                    // send message
                    MessageUtilities.sendMsg(message, event.getTextChannel(), null);
                    // adjust title and footer to reflect future messages are a continuation
                    title = "Events on " + guild.getName() + " (continued)";
                    footer = "(events list continued on next page)";
                }
                // start a new schedule list
                content.append("<#").append(sId).append("> ...\n");
                while (!entries.isEmpty()) {
                    // find and remove the next earliest occurring event
                    ScheduleEntry top = entries.toArray(new ScheduleEntry[entries.size()])[0];
                    for (ScheduleEntry se : entries) {
                        if (se.getStart().isBefore(top.getStart()))
                            top = se;
                    }
                    entries.remove(top);
                    // determine time until the event begins/ends
                    long timeTil = ZonedDateTime.now().until(top.getStart(), ChronoUnit.MINUTES);
                    String status = "begins";
                    if (// adjust if event is ending
                    timeTil < 0) {
                        timeTil = ZonedDateTime.now().until(top.getEnd(), ChronoUnit.MINUTES);
                        status = "ends";
                    }
                    // add the event as a single line in the content
                    content.append(":id:``").append(ParsingUtilities.intToEncodedID(top.getId())).append("`` ~ **").append(top.getTitle()).append("** ").append(status).append(" in *");
                    if (timeTil < 120)
                        content.append(timeTil).append(" minutes*\n");
                    else if (timeTil < 24 * 60)
                        content.append(timeTil / 60).append(" hours and ").append(timeTil % 60).append(" minutes*\n");
                    else
                        content.append(timeTil / (60 * 24)).append(" days*\n");
                    // iterate event counter
                    count++;
                }
                // end a schedule list
                content.append("\n");
            }
        }
    }
    // final footer shows count
    footer = count + " event(s)";
    // build embed and message
    embed = new EmbedBuilder().setFooter(footer, null).setTitle(title).setDescription(content.toString()).build();
    // build message
    Message message = new MessageBuilder().setEmbed(embed).build();
    // send message
    MessageUtilities.sendMsg(message, event.getTextChannel(), null);
}
Also used : ArrayList(java.util.ArrayList) EmbedBuilder(net.dv8tion.jda.core.EmbedBuilder) ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) MessageBuilder(net.dv8tion.jda.core.MessageBuilder) Permission(net.dv8tion.jda.core.Permission)

Example 4 with ScheduleEntry

use of ws.nmathe.saber.core.schedule.ScheduleEntry in project Saber-Bot by notem.

the class EditCommand method verify.

@Override
public String verify(String prefix, String[] args, MessageReceivedEvent event) {
    String head = prefix + this.name();
    int index = 0;
    if (args.length < 1) {
        return "That's not enough arguments! Use ``" + head + " <ID> [<option> <arg>]``";
    }
    // check first arg
    if (!VerifyUtilities.verifyEntryID(args[index])) {
        return "``" + args[index] + "`` is not a valid entry ID!";
    }
    Integer Id = ParsingUtilities.encodeIDToInt(args[index]);
    ScheduleEntry entry = Main.getEntryManager().getEntryFromGuild(Id, event.getGuild().getId());
    if (entry == null) {
        return "I could not find an entry with that ID!";
    }
    if (Main.getScheduleManager().isLocked(entry.getChannelId())) {
        return "Schedule is locked for sorting/syncing. Please try again after sort/sync finishes.";
    }
    // if only one argument, command is valid
    if (args.length == 1)
        return "";
    // 1
    index++;
    // check later args
    ZoneId zone = Main.getScheduleManager().getTimeZone(entry.getChannelId());
    String verify;
    while (index < args.length) {
        switch(args[index++].toLowerCase()) {
            case "c":
            case "comment":
            case "comments":
                if (args.length - index < 1) {
                    return "That's not enough arguments for *comment*!\n" + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [add|remove|swap] <arg(s)>``";
                }
                switch(args[index++].toLowerCase()) {
                    case "a":
                    case "add":
                        verify = VerifyUtilities.verifyCommentAdd(args, index, head);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    case "r":
                    case "remove":
                        verify = VerifyUtilities.verifyCommentRemove(args, index, head, entry);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    case "s":
                    case "swap":
                        verify = VerifyUtilities.verifyCommentSwap(args, index, head, entry);
                        if (!verify.isEmpty())
                            return verify;
                        index += 2;
                        break;
                    default:
                        return "The only valid options for ``comment`` are **add**, **remove**, or **swap**!";
                }
                break;
            case "s":
            case "starts":
            case "start":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments for **" + args[index - 1] + "**!\n" + "Use ``" + head + " " + args[index - 2] + " " + args[index - 1] + " [start time]``";
                }
                if (!VerifyUtilities.verifyTime(args[index])) {
                    return "I could not understand **" + args[index] + "** as a time!" + "\nPlease use the format hh:mm[am|pm].";
                }
                if (ZonedDateTime.of(entry.getStart().toLocalDate(), ParsingUtilities.parseTime(args[index]), entry.getStart().getZone()).isBefore(ZonedDateTime.now())) {
                    return "Today's time is already past *" + args[index] + "*!\n" + "Please use a different time, or change the date for the event!";
                }
                if (entry.hasStarted()) {
                    return "You cannot modify the start time after the event has already started.";
                }
                index++;
                break;
            case "e":
            case "ends":
            case "end":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments for **" + args[index - 1] + "**! " + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [end time]``";
                }
                // if time is not "off" or an invalid time, fail
                if (!VerifyUtilities.verifyTime(args[index]) && !args[index].equalsIgnoreCase("off")) {
                    return "I could not understand **" + args[index] + "** as a time!\n" + "Please use the format hh:mm[am|pm].";
                }
                // if time is not "off" do additional check
                if (!args[index].equalsIgnoreCase("off")) {
                    ZonedDateTime end = ZonedDateTime.of(entry.getEnd().toLocalDate(), ParsingUtilities.parseTime(args[index]), entry.getEnd().getZone());
                    if (end.isBefore(ZonedDateTime.now())) {
                        return "Today's time is already past *" + args[index] + "*!\n" + "Please use a different time, or change the date for the event!";
                    }
                }
                index++;
                break;
            case "t":
            case "title":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments for **" + args[index - 1] + "**! " + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [\"title\"]``";
                }
                if (args[index].length() > 255) {
                    return "Your title can be at most 255 characters!";
                }
                index++;
                break;
            case "d":
            case "date":
            case "sd":
            case "start-date":
            case "ed":
            case "end-date":
                verify = VerifyUtilities.verifyDate(args, index, head, entry, zone);
                if (!verify.isEmpty())
                    return verify;
                index++;
                index++;
                break;
            case "r":
            case "repeats":
            case "repeat":
                verify = VerifyUtilities.verifyRepeat(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "i":
            case "interval":
                verify = VerifyUtilities.verifyInterval(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "im":
            case "image":
            case "th":
            case "thumbnail":
            case "u":
            case "url":
                verify = VerifyUtilities.verifyUrl(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "qs":
            case "quiet-start":
            case "qe":
            case "quiet-end":
            case "qr":
            case "quiet-remind":
            case "quiet-all":
            case "qa":
                break;
            case "ex":
            case "expire":
                verify = VerifyUtilities.verifyExpire(args, index, head, zone);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "limit":
            case "l":
                verify = VerifyUtilities.verifyLimit(args, index, head, entry);
                if (!verify.isEmpty())
                    return verify;
                index += 2;
                break;
            case "deadline":
            case "dl":
                verify = VerifyUtilities.verifyDeadline(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "co":
            case "count":
                verify = VerifyUtilities.verifyCount(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "lo":
            case "location":
                verify = VerifyUtilities.verifyLocation(args, index, head);
                if (!verify.isEmpty())
                    return verify;
                index++;
                break;
            case "an":
            case "announce":
            case "announcement":
            case "announcements":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments for **" + args[index - 1] + "**!\n" + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [add|remove] [#target] [time] [message]``";
                }
                switch(args[index++].toLowerCase()) {
                    case "a":
                    case "add":
                        verify = VerifyUtilities.verifyAnnouncementAdd(args, index, head, event);
                        if (!verify.isEmpty())
                            return verify;
                        index += 3;
                        break;
                    case "r":
                    case "remove":
                        verify = VerifyUtilities.verifyAnnouncementRemove(args, index, head, entry);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    default:
                        return "**" + args[index] + "** is not a valid option!\n" + "You should use either *add* or *remove*!";
                }
                break;
            case "a":
            case "add":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments!\n" + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [announcement|comment] [args]";
                }
                switch(args[index++].toLowerCase()) {
                    case "a":
                    case "an":
                    case "announce":
                    case "announcement":
                    case "announcements":
                        verify = VerifyUtilities.verifyAnnouncementAdd(args, index, head, event);
                        if (!verify.isEmpty())
                            return verify;
                        index += 3;
                        break;
                    case "c":
                    case "comment":
                    case "comments":
                        verify = VerifyUtilities.verifyCommentAdd(args, index, head);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    default:
                        return "*" + args[index - 1] + "* is not a valid option!\n" + "Please use either *comment* or **announcement*!";
                }
                break;
            case "re":
            case "remove":
                if (args.length - index < 1) {
                    return "That's not the right number of arguments!\n" + "Use ``" + head + " " + args[0] + " " + args[index - 1] + " [announcement|comment] [args]";
                }
                switch(args[index++].toLowerCase()) {
                    case "a":
                    case "an":
                    case "announce":
                    case "announcement":
                    case "announcements":
                        verify = VerifyUtilities.verifyAnnouncementRemove(args, index, head, entry);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    case "c":
                    case "comment":
                    case "comments":
                        verify = VerifyUtilities.verifyCommentRemove(args, index, head, entry);
                        if (!verify.isEmpty())
                            return verify;
                        index++;
                        break;
                    default:
                        return "*" + args[index - 1] + "* is not a valid option!\n" + "Please use either *comment* or **announcement*!";
                }
                break;
            default:
                return "**" + args[index - 1] + "** is not an option I know of!\n" + "Please use the ``help`` command to see available options!";
        }
    }
    // return valid
    return "";
}
Also used : ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) ZoneId(java.time.ZoneId) ZonedDateTime(java.time.ZonedDateTime)

Example 5 with ScheduleEntry

use of ws.nmathe.saber.core.schedule.ScheduleEntry in project Saber-Bot by notem.

the class CreateCommand method action.

@Override
public void action(String prefix, String[] args, MessageReceivedEvent event) {
    int index = 0;
    // get schedule ID and zone information
    String cId = args[index++].replaceAll("[^\\d]", "");
    ZoneId zone = Main.getScheduleManager().getTimeZone(cId);
    // Initialize variables
    String title;
    LocalTime startTime;
    // init optional variables with values;
    LocalTime endTime = null;
    int repeat = 0;
    ZonedDateTime startDate = ZonedDateTime.now(zone).plusDays(1);
    ZonedDateTime endDate = null;
    String url = null;
    String image = null;
    String thumbnail = null;
    ZonedDateTime expire = null;
    ZonedDateTime deadline = null;
    Integer count = null;
    String location = null;
    ArrayList<String> comments = new ArrayList<>();
    // process title
    title = args[index];
    index++;
    // process start
    startTime = ParsingUtilities.parseTime(args[index].trim().toUpperCase());
    index++;
    // if minimum args, then ok
    if (args.length != 3) {
        // if <end> fails verification, assume <end> has been omitted
        if (VerifyUtilities.verifyTime(args[index])) {
            endTime = ParsingUtilities.parseTime(args[index].trim().toUpperCase());
            index++;
        }
        // check remaining args
        if (args.length > index) {
            args = Arrays.copyOfRange(args, index, args.length);
            index = 0;
            while (index < args.length) {
                switch(args[index++].toLowerCase().toLowerCase()) {
                    case "d":
                    case "date":
                        startDate = ParsingUtilities.parseDate(args[index].toLowerCase(), zone);
                        endDate = startDate;
                        index++;
                        break;
                    case "sd":
                    case "start date":
                    case "start-date":
                        startDate = ParsingUtilities.parseDate(args[index].toLowerCase(), zone);
                        index++;
                        break;
                    case "ed":
                    case "end date":
                    case "end-date":
                        endDate = ParsingUtilities.parseDate(args[index].toLowerCase(), zone);
                        index++;
                        break;
                    case "r":
                    case "repeats":
                    case "repeat":
                        repeat = EventRecurrence.parseRepeat(args[index].toLowerCase());
                        index++;
                        break;
                    case "i":
                    case "interval":
                        repeat = EventRecurrence.parseInterval(args[index]);
                        index++;
                        break;
                    case "u":
                    case "url":
                        url = ParsingUtilities.parseUrl(args[index]);
                        index++;
                        break;
                    case "ex":
                    case "expire":
                        expire = ParsingUtilities.parseNullableDate(args[index], zone);
                        index++;
                        break;
                    case "im":
                    case "image":
                        image = ParsingUtilities.parseUrl(args[index]);
                        index++;
                        break;
                    case "th":
                    case "thumbnail":
                        thumbnail = ParsingUtilities.parseUrl(args[index]);
                        index++;
                        break;
                    case "deadline":
                    case "dl":
                        deadline = ParsingUtilities.parseNullableDate(args[index], zone);
                        index++;
                        break;
                    case "c":
                    case "count":
                        count = Integer.parseInt(args[index]);
                        index++;
                        break;
                    case "lo":
                    case "location":
                        if (args[index].equalsIgnoreCase("off"))
                            location = null;
                        else
                            location = args[index];
                        index++;
                        break;
                    case "today":
                        startDate = ZonedDateTime.now(zone);
                        endDate = ZonedDateTime.now(zone);
                        break;
                    case "tomorrow":
                        startDate = ZonedDateTime.now(zone).plusDays(1);
                        endDate = ZonedDateTime.now(zone).plusDays(1);
                        break;
                    case "overmorrow":
                        startDate = ZonedDateTime.now(zone).plusDays(2);
                        endDate = ZonedDateTime.now(zone).plusDays(2);
                        break;
                    default:
                        comments.add(args[index - 1]);
                        break;
                }
            }
        }
    }
    /*
         * Finalize the start and end times from
         * the user-provided arguments
         */
    // handle all day events
    // is all day event
    boolean a = startTime.equals(endTime) && startTime.equals(LocalTime.MIN);
    // another way to define all-day events?
    boolean b = startTime.equals(LocalTime.MAX) && endDate == null;
    if (a || b) {
        endDate = ZonedDateTime.from(startDate).plusDays(1);
    }
    // if the end time has not been filled, copy start time
    if (endTime == null) {
        endTime = LocalTime.from(startTime);
    }
    // if the end date has not been filled, copy start date
    if (endDate == null) {
        endDate = ZonedDateTime.from(startDate);
    }
    // create the zoned date time using the schedule's timezone
    ZonedDateTime start = ZonedDateTime.of(startDate.toLocalDate(), startTime, zone);
    ZonedDateTime end = ZonedDateTime.of(endDate.toLocalDate(), endTime, zone);
    // add a year to the date if the provided date is past current time
    Instant now = Instant.now();
    if (now.isAfter(start.toInstant())) {
        start = start.plusYears(1);
    }
    if (now.isAfter(end.toInstant())) {
        end = end.plusYears(1);
    }
    // add a day to end if end is after start
    if (start.isAfter(end)) {
        end = end.plusDays(1);
    }
    /*
         * Create a dummy schedule entry with all processed variables
         * and create the new event via EntryManager
         */
    // create the dummy schedule entry
    ScheduleEntry se = (new ScheduleEntry(event.getGuild().getTextChannelById(cId), title, start, end)).setComments(comments).setRepeat(repeat).setTitleUrl(url).setExpire(expire).setImageUrl(image).setThumbnailUrl(thumbnail).setCount(count).setRsvpDeadline(deadline).setLocation(location);
    // finalize the schedule entry
    Integer entryId = Main.getEntryManager().newEntry(se, true);
    // send the event summary to the command channel
    String body = "New event created :id: **" + ParsingUtilities.intToEncodedID(entryId) + "** on <#" + cId + ">\n" + se.toString();
    MessageUtilities.sendMsg(body, event.getChannel(), null);
}
Also used : ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) ArrayList(java.util.ArrayList)

Aggregations

ScheduleEntry (ws.nmathe.saber.core.schedule.ScheduleEntry)21 JDA (net.dv8tion.jda.core.JDA)6 Main (ws.nmathe.saber.Main)6 ZonedDateTime (java.time.ZonedDateTime)5 java.util (java.util)5 Message (net.dv8tion.jda.core.entities.Message)5 ZoneId (java.time.ZoneId)4 Matcher (java.util.regex.Matcher)4 Pattern (java.util.regex.Pattern)4 Permission (net.dv8tion.jda.core.Permission)4 net.dv8tion.jda.core.entities (net.dv8tion.jda.core.entities)4 StringUtils (org.apache.commons.lang3.StringUtils)4 DateTimeFormatter (java.time.format.DateTimeFormatter)3 ChronoUnit (java.time.temporal.ChronoUnit)3 Consumer (java.util.function.Consumer)3 Collectors (java.util.stream.Collectors)3 MessageReceivedEvent (net.dv8tion.jda.core.events.message.MessageReceivedEvent)3 Document (org.bson.Document)3 MessageUtilities (ws.nmathe.saber.utils.MessageUtilities)3 ParsingUtilities (ws.nmathe.saber.utils.ParsingUtilities)3