summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xpackage-lock.json18
-rwxr-xr-xpackage.json1
-rwxr-xr-xroutes.js43
-rwxr-xr-xviews/event.handlebars32
4 files changed, 93 insertions, 1 deletions
diff --git a/package-lock.json b/package-lock.json
index 2e1d899..91e1ef5 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -2810,6 +2810,24 @@
"rrule": "2.4.1"
}
},
+ "ical-generator": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/ical-generator/-/ical-generator-1.9.2.tgz",
+ "integrity": "sha512-z3OLKk/b9TbyOLKOIMpjLJ3u7gq/tXPNsH5uOz+Ai3sqn2kcpjFlZUafKrlduwZn3Xu3fV5WqZ2dddZFrhQTfg==",
+ "requires": {
+ "moment-timezone": "^0.5.27"
+ },
+ "dependencies": {
+ "moment-timezone": {
+ "version": "0.5.27",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz",
+ "integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==",
+ "requires": {
+ "moment": ">= 2.9.0"
+ }
+ }
+ }
+ },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
diff --git a/package.json b/package.json
index fff1c2d..04f8a15 100755
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"greenlock": "^2.6.7",
"greenlock-express": "^2.6.7",
"ical": "^0.6.0",
+ "ical-generator": "^1.9.2",
"jimp": "^0.6.0",
"jsonwebtoken": "^8.4.0",
"marked": "^0.7.0",
diff --git a/routes.js b/routes.js
index ee723e2..f2bca02 100755
--- a/routes.js
+++ b/routes.js
@@ -62,6 +62,11 @@ render_plain = function () {
}
const ical = require('ical');
+const icalGenerator = require('ical-generator');
+const cal = icalGenerator({
+ domain: 'gath.io',
+ name: 'Gathio'
+});
const sgMail = require('@sendgrid/mail');
@@ -408,6 +413,42 @@ router.get('/group/:eventGroupID', (req, res) => {
});
})
+router.get('/exportevent/:eventID', (req, res) => {
+ Event.findOne({
+ id: req.params.eventID
+ })
+ .populate('eventGroup')
+ .then((event) => {
+ if (event) {
+ const icalEvent = cal.createEvent({
+ start: moment.tz(event.start, event.timezone),
+ end: moment.tz(event.start, event.timezone),
+ timezone: event.timezone,
+ timestamp: moment(),
+ summary: event.name,
+ description: event.description,
+ organizer: {
+ name: event.hostName ? event.hostName : "Anonymous",
+ email: event.creatorEmail
+ },
+ location: event.location,
+ url: 'https://gath.io/' + event.id
+ });
+
+ let string = cal.toString();
+ console.log(string)
+ res.send(string);
+ }
+ })
+ .catch((err) => {
+ addToLog("exportEvent", "error", "Attempt to export event " + req.params.eventID + " failed with error: " + err);
+ console.log(err)
+ res.status(404);
+ res.render('404', { url: req.url });
+ return;
+ });
+})
+
// BACKEND ROUTES
//router.post('/login',
@@ -529,7 +570,7 @@ router.post('/importevent', (req, res) => {
image: '',
creatorEmail: creatorEmail,
url: '',
- hostName: importedEventData.organizer ? importedEventData.organizer.params.CN : "",
+ hostName: importedEventData.organizer ? importedEventData.organizer.params.CN.replace(/["]+/g, '') : "",
viewPassword: '',
editPassword: '',
editToken: editToken,
diff --git a/views/event.handlebars b/views/event.handlebars
index 4d0cf28..70c4018 100755
--- a/views/event.handlebars
+++ b/views/event.handlebars
@@ -45,6 +45,9 @@
<a href="http://www.google.com/calendar/event?action=TEMPLATE&dates={{parsedStart}}%2F{{parsedEnd}}&text={{escapedName}}&location={{parsedLocation}}&ctz={{timezone}}" class="eventInformationAction btn btn-outline-secondary btn-sm">
<i class="far fa-calendar-plus"></i> Add to Google Calendar
</a>
+ <button type="button" id="exportICS" class="eventInformationAction btn btn-outline-secondary btn-sm" data-event-id="{{eventData.id}}">
+ <i class="fas fa-download"></i> Export as ICS
+ </button>
</li>
{{#if eventHasHost}}
<li>
@@ -375,6 +378,29 @@
})
$(document).ready(function() {
+ // From https://davidwalsh.name/javascript-download
+ function downloadFile(data, fileName, type="text/plain") {
+ // Create an invisible A element
+ const a = document.createElement("a");
+ a.style.display = "none";
+ document.body.appendChild(a);
+
+ // Set the HREF to a Blob representation of the data to be downloaded
+ a.href = window.URL.createObjectURL(
+ new Blob([data], { type })
+ );
+
+ // Use download attribute to set set desired file name
+ a.setAttribute("download", fileName);
+
+ // Trigger the download by simulating click
+ a.click();
+
+ // Cleanup
+ window.URL.revokeObjectURL(a.href);
+ document.body.removeChild(a);
+ }
+
$.uploadPreview({
input_field: "#image-upload",
preview_box: "#image-preview",
@@ -394,6 +420,12 @@
{{/if}}
new ClipboardJS('#copyEventLink');
autosize($('textarea'));
+ $("#exportICS").click(function(){
+ let eventID = $(this).attr('data-event-id');
+ $.get('/exportevent/' + eventID, function(response) {
+ downloadFile(response, eventID + '.ics');
+ })
+ })
$("#copyEventLink").click(function(){
$(this).html('<i class="fas fa-copy"></i> Copied!');
setTimeout(function(){ $("#copyEventLink").html('<i class="fas fa-copy"></i> Copy');}, 5000);