2022-10-11 16:29:49 -04:00
const { ICalParser } = require ( 'cozy-ical' ) ;
const { URL } = require ( 'url' ) ;
const { Constants } = require ( 'discord.js' ) ;
const request = require ( 'request' ) ;
const { verPremium } = require ( '../premium/verifyPremium.js' ) ;
2022-12-19 17:20:04 -05:00
const { isValidUrl } = require ( '../dev only/setPresence.js' ) ;
2022-10-11 16:29:49 -04:00
//#region SET REMINDERS
function addReminder ( interaction , bot , obj , Id ) {
return new Promise ( ( resolve , reject ) => {
try {
bot . mongoconnection . then ( ( client ) => {
// Update the Key object first to check if the time is already there
const kbo = client . db ( 'main' ) . collection ( 'reminderKeys' ) ;
kbo . findOne ( ( { 'userId' : Id } ) ) . then ( ( doc ) => {
const t = obj . time . toString ( ) ;
try {
if ( doc . times . indexOf ( obj . time ) == - 1 ) {
kbo . updateOne ( { 'userId' : Id } , { $push : { times : t } } )
} else {
//Event already exists at this time
reject ( "An event already exists at this time!" ) ;
return ; // interaction.channel.send("An event already exists at this time!");
}
//Update the Time object
const dbo = client . db ( 'main' ) . collection ( 'reminders' ) ;
dbo . findOne ( { time : t } ) . then ( ( doc ) => {
let n = 0 ;
if ( doc ) {
n = doc . amt ;
doc . amt ++ ;
doc [ ` ${ n } ` ] = obj . event ;
dbo . findOneAndReplace ( { time : t } , doc ) ;
} else {
const d = new Date ( Number ( obj . time ) ) ;
doc = { "0" : obj . event , "time" : t , "month" : d . getMonth ( ) , "amt" : 1 } ; //Month used for clearing when the calendar month begins (maybe modify the garbage collection with an `else if (day == 1? clear last month)` )
dbo . insertOne ( doc ) ;
}
//Reply with the reminder in correct format
// interaction.reply({ content: "REMINDER SAVED!", embeds: [embd], ephemeral: true });
resolve ( true ) ;
} ) . catch ( ( err ) => {
console . error ( err ) ;
// interaction.reply("Uh Oh! An error has occured!");
} ) ;
} catch ( err ) {
console . error ( err ) ; //interaction.reply("Uh Oh! An error has occured!");
reject ( err ) ;
}
} ) . catch ( ( err ) => {
console . log ( "ERR" ) ;
console . error ( err ) ;
reject ( false ) ;
// interaction.reply("Uh Oh! An error has occured!");
} ) ;
} ) ;
} catch ( err ) {
console . error ( err ) ;
// return interaction.reply("Uh Oh! An error has occured!"); // Gets "acknowledged" too many times
}
} ) ;
}
//#endregion
//#region SETUP AND PARSING
class calClass {
constructor ( vevent ) {
const model = vevent . model ;
const alarms = vevent . subComponents ;
if ( alarms && alarms [ 0 ] && alarms [ 0 ] . model ) {
let temp = alarms [ 0 ] . model . trigger ;
temp = temp . split ( 'DT' ) [ 1 ] ;
temp = temp . split ( "H" ) ;
let hours = ( temp [ 0 ] && temp [ 0 ] != '0' ) ? Number ( temp [ 0 ] ) : 0 ;
let minutesStr = temp [ 1 ] . split ( 'M' ) [ 0 ] ;
let minutes = ( minutesStr && ! isNaN ( minutesStr ) ) ? hours + Number ( minutesStr ) : hours ;
this . offset = minutes ;
} else {
this . offset = 0 ;
}
this . name = model . summary ;
this . description = ( model . description ) ? model . description : "N/A" ;
const dateTime = new Date ( model . startDate ) ;
this . time = dateTime . getTime ( ) / 1000 ;
if ( isValidUrl ( model . location ) ) {
this . url = model . location || undefined ;
this . loc = undefined ;
} else {
this . url = undefined ;
this . loc = model . location || undefined ;
}
}
isValidUrl ( s ) {
try {
new URL ( s ) ;
return true ;
} catch ( err ) {
return false ;
}
}
exportAsObj ( gid , uid ) {
const obj = { time : this . time , event : { guildId : gid , userId : uid , name : this . name , description : this . description , offset : this . offset , link : this . url , location : this . loc } }
return obj ;
}
}
function parseData ( calStr , gid , uid ) {
return new Promise ( ( resolve , reject ) => {
const parser = new ICalParser ( ) ;
parser . parseString ( calStr , function ( err , cal ) {
try {
const arr = [ ] ;
for ( i in cal . subComponents ) {
const a = new calClass ( cal . subComponents [ i ] ) ;
arr . push ( a . exportAsObj ( gid , uid ) ) ;
}
resolve ( arr ) ;
} catch ( err ) {
console . log ( err ) ;
reject ( err ) ;
}
} ) ;
} ) ;
}
/**
* @param {String} fileName
*/
function readFileAndParse ( url , bot , interaction , gid , uid ) {
request . get ( url , function ( error , response , body ) {
try {
if ( ! error && response . statusCode == 200 ) {
const isGuild = ( gid && ! uid ) || false ;
const notAdded = [ ] ;
const Id = ( isGuild ) ? gid : uid ;
parseData ( body , gid , uid ) . then ( ( arr ) => {
new Promise ( ( resolve , reject ) => {
// If the key does not exist, create it
if ( arr . length > 0 ) {
bot . mongoconnection . then ( ( client ) => {
const kbo = client . db ( 'main' ) . collection ( 'reminderKeys' ) ;
kbo . findOne ( ( { 'userId' : Id } ) ) . then ( ( doc ) => {
if ( ! doc ) {
doc = { userId : Id , times : [ ] }
kbo . insertOne ( doc ) ;
reject ( "New user created, please try again!" ) ;
} else {
resolve ( true ) ;
}
} ) ;
} ) ;
} else {
reject ( "No data..." ) ;
}
// const m = new Map(arr.map((obj, ind) => { return [ind, obj]; }));
} ) . then ( ( ) => {
Promise . all ( arr . map ( ( obj , ind ) => {
addReminder ( interaction , bot , obj , Id ) . then ( ( ) => { } )
. catch ( ( err ) => {
notAdded . push ( err ) ;
} ) ;
} ) ) . then ( ( t ) => {
const r1 = { content : ` ITEMS NOT ADDED: \n ${ notAdded . join ( "\n" ) } ` , ephemeral : true }
if ( r1 . content != "ITEMS NOT ADDED:\n" ) {
interaction . reply ( r1 ) . catch ( ( err ) => { interaction . channel . send ( r1 ) ; } ) ;
} else {
const r2 = ` All ${ arr . length } items added to calendar! ` ;
interaction . reply ( r2 ) . catch ( ( err ) => { interaction . channel . send ( r2 ) ; } ) ;
}
} ) ;
} ) . catch ( ( err ) => {
interaction . reply ( err ) ;
} )
} ) . catch ( ( err ) => {
console . log ( err ) ;
} ) ;
}
} catch ( err ) {
console . log ( err ) ;
interaction . reply ( { content : "Uh oh, there's been an error!" , ephemeral : true } ) ;
}
} ) ;
}
//#endregion
module . exports = {
name : 'import_ics' ,
description : 'Import events using a calendar' ,
async execute ( interaction , Discord , Client , bot ) {
//Check if the user has premium
await verPremium ( bot , interaction . user . id ) . then ( ( ) => {
const url = interaction . options . data [ 0 ] . attachment . attachment ;
if ( ! url . endsWith ( ".ics" ) ) {
return interaction . reply ( "Please use a valid ***.ics*** file!" )
}
let uid , gid ;
if ( interaction . channel . type == 'DM' ) {
uid = interaction . user . id ;
} else {
gid = interaction . guildId ;
}
readFileAndParse ( url , bot , interaction , gid , uid ) ;
} ) . catch ( ( ) => {
interaction . reply ( "You have to be a premium subscriber to use this feature!" ) ;
} ) ;
} ,
options : [
{ name : 'ics_file' , description : 'The ics file to input' , type : Constants . ApplicationCommandOptionTypes . ATTACHMENT , required : true } ,
] ,
isDm : true
}