Search in sources :

Example 1 with JDA

use of net.dv8tion.jda.api.JDA in project Saber-Bot by notem.

the class ShardsCommand method action.

@Override
public void action(String prefix, String[] args, MessageReceivedEvent event) {
    Consumer<String> sendMsg = (msg) -> {
        if (event.isFromType(ChannelType.PRIVATE)) {
            MessageUtilities.sendPrivateMsg(msg, event.getAuthor(), null);
        } else {
            MessageUtilities.sendMsg(msg, event.getTextChannel(), null);
        }
    };
    String msg = "I am not sharded!";
    if (Main.getShardManager().isSharding()) {
        msg = "```javascript\n" + "\"Total Shards\" (" + Main.getBotSettingsManager().getShardTotal() + ")\n";
        for (JDA shard : Main.getShardManager().getShards()) {
            JDA.ShardInfo info = shard.getShardInfo();
            msg += "\n[Shard-" + info.getShardId() + "]\n" + "       Status: \"" + shard.getStatus().toString() + "\"\n" + "         Ping: \"" + shard.getGatewayPing() + "\"\n" + "       Guilds: \"" + shard.getGuilds().size() + "\"\n" + "        Users: \"" + shard.getUsers().size() + "\"\n" + "ResponseTotal: \"" + shard.getResponseTotal() + "\"\n";
            if (msg.length() > 1900) {
                msg += "```";
                sendMsg.accept(msg);
                msg = "```javascript\n";
            }
        }
        msg += "```";
    }
    sendMsg.accept(msg);
}
Also used : Consumer(java.util.function.Consumer) Command(ws.nmathe.saber.commands.Command) JDA(net.dv8tion.jda.api.JDA) CommandInfo(ws.nmathe.saber.commands.CommandInfo) MessageUtilities(ws.nmathe.saber.utils.MessageUtilities) Main(ws.nmathe.saber.Main) MessageReceivedEvent(net.dv8tion.jda.api.events.message.MessageReceivedEvent) ChannelType(net.dv8tion.jda.api.entities.ChannelType) JDA(net.dv8tion.jda.api.JDA)

Example 2 with JDA

use of net.dv8tion.jda.api.JDA 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().isSchedule(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()) {
            try // convert the list of Google Events into discord event entries
            {
                // 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();
                            Logging.info(this.getClass(), comment);
                            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 = ZonedDateTime.of(ParsingUtilities.parseDate(tmp, zone), LocalTime.MAX, 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);
                }
            } catch (Exception e) {
                Logging.exception(this.getClass(), e);
            }
        }
        // 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.getManager().setTopic(calLink).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 : Message(net.dv8tion.jda.api.entities.Message) Document(org.bson.Document) java.util(java.util) JDA(net.dv8tion.jda.api.JDA) Permission(net.dv8tion.jda.api.Permission) EventRecurrence(ws.nmathe.saber.core.schedule.EventRecurrence) Logging(ws.nmathe.saber.utils.Logging) IOException(java.io.IOException) TextChannel(net.dv8tion.jda.api.entities.TextChannel) ScheduleEntry(ws.nmathe.saber.core.schedule.ScheduleEntry) Bson(org.bson.conversions.Bson) Consumer(java.util.function.Consumer) Filters(com.mongodb.client.model.Filters) com.google.api.services.calendar.model(com.google.api.services.calendar.model) DateTime(com.google.api.client.util.DateTime) java.time(java.time) DateTimeFormatter(java.time.format.DateTimeFormatter) EntryManager(ws.nmathe.saber.core.schedule.EntryManager) MessageUtilities(ws.nmathe.saber.utils.MessageUtilities) Calendar(com.google.api.services.calendar.Calendar) Main(ws.nmathe.saber.Main) VerifyUtilities(ws.nmathe.saber.utils.VerifyUtilities) ParsingUtilities(ws.nmathe.saber.utils.ParsingUtilities) Message(net.dv8tion.jda.api.entities.Message) JDA(net.dv8tion.jda.api.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 3 with JDA

use of net.dv8tion.jda.api.JDA in project Saber-Bot by notem.

the class EntryManager method newEntry.

/**
 * Create a new entry on a schedule
 * @param se (ScheduleEntry) the base ScheduleEntry object to use
 */
public Integer newEntry(ScheduleEntry se, boolean sort) {
    // identify which shard is responsible for the schedule
    String guildId = se.getGuildId();
    String channelId = se.getChannelId();
    JDA jda = Main.getShardManager().getJDA(guildId);
    // generate the reminders
    se.reloadReminders(Main.getScheduleManager().getReminders(se.getChannelId())).reloadEndReminders(Main.getScheduleManager().getEndReminders(se.getChannelId()));
    // process expiration date
    Date expire = null;
    if (se.getExpire() != null) {
        expire = Date.from(se.getExpire().toInstant());
    }
    // process deadline
    Date deadline = null;
    if (se.getDeadline() != null) {
        deadline = Date.from(se.getDeadline().toInstant());
    }
    // is rsvp enabled on the channel set empty rsvp lists
    if (Main.getScheduleManager().isRSVPEnabled(se.getChannelId())) {
        for (String type : Main.getScheduleManager().getRSVPOptions(se.getChannelId()).values()) {
            se.setRsvpMembers(type, new ArrayList<>());
        }
    }
    // generate event display message
    se.setId(this.newId());
    Message message = MessageGenerator.generate(se);
    // send message to schedule
    TextChannel channel = jda.getTextChannelById(channelId);
    Date finalExpire = expire;
    Date finalDeadline = deadline;
    MessageUtilities.sendMsg(message, channel, msg -> {
        try {
            // add reaction options if rsvp is enabled
            if (Main.getScheduleManager().isRSVPEnabled(channelId)) {
                Map<String, String> map = Main.getScheduleManager().getRSVPOptions(channelId);
                addRSVPReactions(map, Main.getScheduleManager().getRSVPClear(channelId), msg, se);
            }
            // add new document
            Document entryDocument = new Document("_id", se.getId()).append("title", se.getTitle()).append("start", Date.from(se.getStart().toInstant())).append("end", Date.from(se.getEnd().toInstant())).append("comments", se.getComments()).append("recurrence", se.getRepeat()).append("reminders", se.getReminders()).append("end_reminders", se.getEndReminders()).append("url", se.getTitleUrl()).append("hasStarted", se.hasStarted()).append("messageId", msg.getId()).append("channelId", se.getChannelId()).append("googleId", se.getGoogleId()).append("rsvp_members", se.getRsvpMembers()).append("rsvp_limits", se.getRsvpLimits()).append("image", se.getImageUrl()).append("thumbnail", se.getThumbnailUrl()).append("orig_start", Date.from(se.getRecurrence().getOriginalStart().toInstant())).append("count", se.getRecurrence().getCount()).append("start_disabled", false).append("end_disabled", false).append("reminders_disabled", false).append("expire", finalExpire).append("deadline", finalDeadline).append("guildId", se.getGuildId()).append("location", se.getLocation()).append("description", se.getDescription()).append("color", se.getColor());
            Main.getDBDriver().getEventCollection().insertOne(entryDocument);
            // auto-sort the schedule if configured
            autoSort(sort, channelId);
        } catch (Exception e) {
            Logging.exception(EntryManager.class, e);
        }
    });
    return se.getId();
}
Also used : TextChannel(net.dv8tion.jda.api.entities.TextChannel) Message(net.dv8tion.jda.api.entities.Message) JDA(net.dv8tion.jda.api.JDA) Document(org.bson.Document) MongoException(com.mongodb.MongoException)

Example 4 with JDA

use of net.dv8tion.jda.api.JDA in project Saber-Bot by notem.

the class ScheduleEntry method getMessageObject.

/**
 * Attempts to retrieve the discord Message, if the message does not exist
 * (or the bot can for any other reason cannot retrieve it) the method returns null
 * @return (Message) if exists, otherwise null
 */
public void getMessageObject(Consumer<Message> success) {
    JDA jda = Main.getShardManager().isSharding() ? Main.getShardManager().getShard(guildId) : Main.getShardManager().getJDA();
    TextChannel channel = jda.getTextChannelById(this.chanId);
    if (channel != null) {
        channel.retrieveMessageById(this.msgId).queue(success);
    }
}
Also used : JDA(net.dv8tion.jda.api.JDA)

Example 5 with JDA

use of net.dv8tion.jda.api.JDA in project Saber-Bot by notem.

the class ScheduleSyncer method run.

public void run() {
    Logging.info(this.getClass(), "Running schedule syncer. . .");
    Bson query = and(ne("sync_address", "off"), lte("sync_time", new Date()));
    Main.getDBDriver().getScheduleCollection().find(query).projection(fields(include("_id", "sync_time", "sync_address", "sync_user", "guildId"))).forEach((Consumer<? super Document>) document -> {
        executor.execute(() -> {
            try {
                String guildId = document.getString("guildId");
                JDA jda = Main.getShardManager().getJDA(guildId);
                if (jda == null)
                    return;
                if (JDA.Status.valueOf("CONNECTED") != jda.getStatus())
                    return;
                String scheduleId = document.getString("_id");
                Date syncTime = Date.from(ZonedDateTime.ofInstant(document.getDate("sync_time").toInstant(), Main.getScheduleManager().getTimeZone(scheduleId)).plusDays(1).toInstant());
                Main.getDBDriver().getScheduleCollection().updateOne(eq("_id", scheduleId), set("sync_time", syncTime));
                String address = document.getString("sync_address");
                Credential credential = document.get("sync_user") == null ? GoogleAuth.authorize() : GoogleAuth.getCredential(document.getString("sync_user"));
                Calendar service = GoogleAuth.getCalendarService(credential);
                TextChannel channel = jda.getTextChannelById(document.getString("_id"));
                if (channel == null)
                    return;
                if (Main.getCalendarConverter().checkValidAddress(address, service)) {
                    Main.getCalendarConverter().importCalendar(address, channel, service);
                    Logging.info(this.getClass(), "Synchronized schedule #" + channel.getName() + " [" + document.getString("_id") + "] on '" + channel.getGuild().getName() + "' [" + channel.getGuild().getId() + "]");
                } else {
                    GuildSettingsManager.GuildSettings gs = Main.getGuildSettingsManager().getGuildSettings(guildId);
                    TextChannel control = Main.getShardManager().getJDA(guildId).getTextChannelById(gs.getCommandChannelId());
                    String content = "**Warning:** I failed to auto-sync <#" + scheduleId + "> to *" + address + "*!\n" + "Please make sure that the calendar address is still correct and that the calendar privacy settings have not changed!";
                    MessageUtilities.sendMsg(content, control, null);
                    Logging.warn(this.getClass(), "Failed to synchronize schedule #" + channel.getName() + " [" + document.getString("_id") + "] on '" + channel.getGuild().getName() + "' [" + channel.getGuild().getId() + "]");
                }
            } catch (Exception e) {
                Logging.exception(this.getClass(), e);
            }
        });
    });
}
Also used : ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) Document(org.bson.Document) JDA(net.dv8tion.jda.api.JDA) Date(java.util.Date) Projections.fields(com.mongodb.client.model.Projections.fields) Logging(ws.nmathe.saber.utils.Logging) ZonedDateTime(java.time.ZonedDateTime) TextChannel(net.dv8tion.jda.api.entities.TextChannel) Updates.set(com.mongodb.client.model.Updates.set) GoogleAuth(ws.nmathe.saber.core.google.GoogleAuth) Executors(java.util.concurrent.Executors) Projections.include(com.mongodb.client.model.Projections.include) Bson(org.bson.conversions.Bson) Consumer(java.util.function.Consumer) Filters(com.mongodb.client.model.Filters) GuildSettingsManager(ws.nmathe.saber.core.settings.GuildSettingsManager) MessageUtilities(ws.nmathe.saber.utils.MessageUtilities) Credential(com.google.api.client.auth.oauth2.Credential) Calendar(com.google.api.services.calendar.Calendar) Main(ws.nmathe.saber.Main) Main.getGuildSettingsManager(ws.nmathe.saber.Main.getGuildSettingsManager) ExecutorService(java.util.concurrent.ExecutorService) Credential(com.google.api.client.auth.oauth2.Credential) TextChannel(net.dv8tion.jda.api.entities.TextChannel) JDA(net.dv8tion.jda.api.JDA) Calendar(com.google.api.services.calendar.Calendar) Date(java.util.Date) Bson(org.bson.conversions.Bson)

Aggregations

JDA (net.dv8tion.jda.api.JDA)24 Document (org.bson.Document)7 Main (ws.nmathe.saber.Main)7 Consumer (java.util.function.Consumer)6 Permission (net.dv8tion.jda.api.Permission)6 PermissionException (net.dv8tion.jda.api.exceptions.PermissionException)6 Logging (ws.nmathe.saber.utils.Logging)5 TextChannel (net.dv8tion.jda.api.entities.TextChannel)4 Bson (org.bson.conversions.Bson)4 Filters (com.mongodb.client.model.Filters)3 Projections.fields (com.mongodb.client.model.Projections.fields)3 Projections.include (com.mongodb.client.model.Projections.include)3 ZonedDateTime (java.time.ZonedDateTime)3 ChronoUnit (java.time.temporal.ChronoUnit)3 java.util (java.util)3 Collectors (java.util.stream.Collectors)3 Guild (net.dv8tion.jda.api.entities.Guild)3 Message (net.dv8tion.jda.api.entities.Message)3 MessageUtilities (ws.nmathe.saber.utils.MessageUtilities)3 Calendar (com.google.api.services.calendar.Calendar)2