├── package.json ├── LICENSE ├── example └── example.js ├── lib └── icalevent.js └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "icalevent", 3 | "version": "0.3.0", 4 | "description": "Create an iCalEvent instance by setting limited properties and get an ics formatted string.", 5 | "keywords": ["ical", "ics"], 6 | "repository": "git://github.com/shanebo/icalevent.git", 7 | "author": "Shane Thacker ", 8 | "dependencies": { 9 | "tzone": "0.0.2" 10 | }, 11 | "engine": ">= 0.4.1", 12 | "main": "./lib/icalevent" 13 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012 Shane Thacker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /example/example.js: -------------------------------------------------------------------------------- 1 | 2 | var iCalEvent = require('icalevent'); 3 | var tzone = require('tzone'); 4 | var http = require('http'); 5 | 6 | 7 | var event = new iCalEvent({ 8 | offset: new Date().getTimezoneOffset(), 9 | start: '2014-07-01T02:00:00-05:00', 10 | end: '2014-07-01T02:30:00-05:00', 11 | summary: 'Priestly Duties', 12 | description: 'Home flu visit.', 13 | location: 'Casa', 14 | organizer: { 15 | name: 'Nacho Libre', 16 | email: 'luchador@monastery.org' 17 | }, 18 | url: 'http://google.com/search?q=nacho+libre' 19 | }); 20 | 21 | 22 | // or 23 | 24 | 25 | var e = new iCalEvent(); 26 | e.set('offset', new Date().getTimezoneOffset()); 27 | e.set('start', '2014-07-01T02:00:00-05:00'); 28 | e.set('end', '2014-07-01T02:30:00-05:00'); 29 | e.set('summary', 'Priestly Duties.'); 30 | e.set('description', 'Home flu visit.'); 31 | e.set('location', 'Casa'); 32 | e.set('organizer', { name: 'Nacho Libre', email: 'luchador@monastery.org' }); 33 | e.set('url', 'http://google.com/search?q=nacho+libre'); 34 | 35 | 36 | console.log('\n'); 37 | console.log(e.toFile()); 38 | 39 | 40 | http.createServer(function(request, response){ 41 | response.writeHead(200, {'Content-Type': 'text/calendar'}); 42 | var file = event.toFile(); 43 | response.end(file); 44 | }).listen(9999, '127.0.0.1'); 45 | 46 | 47 | console.log('Server running at http://127.0.0.1:9999/'); -------------------------------------------------------------------------------- /lib/icalevent.js: -------------------------------------------------------------------------------- 1 | var tzone = require('tzone'); 2 | 3 | 4 | var iCalEvent = function(event){ 5 | this.id = '-//iCalEvent.js v0.3//EN'; 6 | this.uid = this.uid(); 7 | this.event = {}; 8 | if (event) this.create(event); 9 | } 10 | 11 | iCalEvent.prototype = { 12 | 13 | create: function(event){ 14 | for (var key in event) { 15 | if (event.hasOwnProperty(key)) this.set(key, event[key]); 16 | } 17 | }, 18 | 19 | uid: function(){ 20 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c){ 21 | var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); 22 | return v.toString(16); 23 | }); 24 | }, 25 | 26 | format: function(datetime){ 27 | function pad(n){ 28 | return (n < 10 ? '0' : '') + n; 29 | } 30 | 31 | var d = new Date(datetime); 32 | d.setUTCMinutes(d.getUTCMinutes() - this.event.offset); 33 | 34 | padded = (d.getUTCFullYear() 35 | + pad(d.getUTCMonth() + 1) 36 | + pad(d.getUTCDate()) + 'T' 37 | + pad(d.getUTCHours()) 38 | + pad(d.getUTCMinutes()) 39 | + pad(d.getUTCSeconds())); 40 | 41 | return padded; 42 | }, 43 | 44 | get: function(key){ 45 | if (this.event[key]) return this.event[key]; 46 | }, 47 | 48 | set: function(key, value){ 49 | if (this[key]) this[key](value) 50 | else this.event[key] = value; 51 | }, 52 | 53 | start: function(datetime){ 54 | var d = new Date(datetime); 55 | d.setUTCMinutes(d.getUTCMinutes() - this.event.offset); 56 | this.event.timezone = tzone.getLocation(d); 57 | this.event.start = this.format(datetime); 58 | }, 59 | 60 | end: function(datetime){ 61 | this.event.end = this.format(datetime); 62 | }, 63 | 64 | toFile: function(){ 65 | var result = ''; 66 | 67 | result += 'BEGIN:VCALENDAR\r\n'; 68 | result += 'VERSION:2.0\r\n'; 69 | //It it is a request 70 | if(this.event.isRequest) result += 'METHOD:REQUEST\r\n'; 71 | result += 'PRODID:' + this.id + '\r\n'; 72 | result += 'BEGIN:VEVENT\r\n'; 73 | result += 'UID:' + this.uid + '\r\n'; 74 | result += 'DTSTAMP:' + this.format(new Date()) + '\r\n'; 75 | result += 'STATUS:CONFIRMED\r\n'; 76 | //Making RSVP for each attendee on the Request 77 | if(this.event.isRequest && !!this.event.attendees){ 78 | for(x in this.event.attendees){ 79 | result +='ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="'+this.event.attendees[x].name+'":MAILTO:'+this.event.attendees[x].email+ '\r\n'; 80 | } 81 | } 82 | if (this.event.start) result += 'DTSTART;TZID=' + this.event.timezone + ':' + this.event.start + '\r\n'; 83 | if (this.event.end) result += 'DTEND;TZID=' + this.event.timezone + ':' + this.event.end + '\r\n'; 84 | if (this.event.summary) result += 'SUMMARY:' + this.event.summary + '\r\n'; 85 | if (this.event.description) result += 'DESCRIPTION:' + this.event.description + '\r\n'; 86 | if (this.event.organizer) result += 'ORGANIZER;CN=' + this.event.organizer.name + ':mailto:' + this.event.organizer.email + '\r\n'; 87 | if (this.event.location) result += 'LOCATION:' + this.event.location + '\r\n'; 88 | if (this.event.url) result += 'URL;VALUE=URI:' + this.event.url + '\r\n'; 89 | 90 | result += 'END:VEVENT\r\n'; 91 | result += 'END:VCALENDAR\r\n'; 92 | 93 | return result; 94 | } 95 | 96 | } 97 | 98 | 99 | module.exports = iCalEvent; 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iCalEvent 2 | 3 | Create an iCalEvent instance by setting limited properties and event.toFile() to get an ics formatted string back. 4 | 5 | ## Install 6 | 7 | With [npm](http://npmjs.org): 8 | 9 | npm install icalevent 10 | 11 | 12 | ## Examples 13 | 14 | ``` js 15 | var iCalEvent = require('icalevent'); 16 | 17 | var event = new iCalEvent({ 18 | offset: new Date().getTimezoneOffset(), 19 | start: '2014-07-01T02:00:00-05:00', 20 | end: '2014-07-01T02:30:00-05:00', 21 | summary: 'Priestly Duties', 22 | description: 'Home flu visit.', 23 | location: 'Casa', 24 | url: 'http://google.com/search?q=nacho+libre', 25 | organizer: { 26 | name: 'Nacho Libre', 27 | email: 'luchador@monastery.org' 28 | } 29 | }); 30 | ``` 31 | 32 | Or: 33 | 34 | ``` js 35 | var iCalEvent = require('icalevent'); 36 | 37 | var event = new iCalEvent(); 38 | 39 | event.set('offset', new Date().getTimezoneOffset()); 40 | event.set('start', '2014-07-01T02:00:00-05:00'); 41 | event.set('end', '2014-07-01T02:30:00-05:00'); 42 | event.set('summary', 'Priestly Duties'); 43 | event.set('description', 'Home flu visit.'); 44 | event.set('location', 'Casa'); 45 | event.set('url', 'http://google.com/search?q=nacho+libre'); 46 | event.set('organizer', {name: 'Nacho Libre', email: 'luchador@monastery.org'}); 47 | ``` 48 | 49 | To ics string: 50 | 51 | ``` js 52 | event.toFile(); 53 | ``` 54 | 55 | Returns: 56 | 57 | ``` 58 | BEGIN:VCALENDAR 59 | VERSION:2.0 60 | PRODID:-//iCalEvent.js v0.3//EN 61 | BEGIN:VEVENT 62 | UID:d8dbbc27-7f97-4d83-9fdf-bb45d382ffdc 63 | DTSTAMP:20131208T033712 64 | DTSTART;TZID=US/Central:20140701T010000 65 | DTEND;TZID=US/Central:20140701T013000 66 | SUMMARY:Priestly Duties. 67 | DESCRIPTION:Home flu visit. 68 | ORGANIZER;CN=Nacho Libre:mailto:luchador@monastery.org 69 | LOCATION:Casa 70 | URL;VALUE=URI:http://google.com/search?q=nacho+libre 71 | END:VEVENT 72 | END:VCALENDAR 73 | ``` 74 | 75 | ## API 76 | 77 | ### Properties 78 | 79 | #### Required 80 | 81 | * **offset** (Integer) _The Date.getTimezoneOffset() of the timezone the event is set in. Important: the offset has to be set before start and end times_ 82 | * **start** (Date Object) _The start date object of the event_ 83 | * **end** (Date Object) _The end date object of the event_ 84 | 85 | #### Optional 86 | 87 | * **location** (String) _The event location of the event. For example, monastery_ 88 | * **url** (String) _A url corresponding to the event_ 89 | * **summary** (String) _A summary of the event_ 90 | * **description** (String) _A description of the event_ 91 | * **organizer** (Object) _The organizer object in the following format:_ 92 | 93 | ``` js 94 | { 95 | name: 'Nacho Libre', 96 | email: 'luchador@monastery.org' 97 | } 98 | ``` 99 | 100 | 101 | 102 | ### Methods 103 | 104 | #### .set(property, value) 105 | ``` js 106 | event.set('url', 'http://google.com/search?q=nacho+libre'); 107 | ``` 108 | 109 | #### .get(property) 110 | ``` js 111 | event.get('url'); 112 | ``` 113 | 114 | Returns: 115 | 116 | ``` 117 | http://google.com/search?q=nacho+libre 118 | ``` 119 | 120 | #### .toFile() 121 | ``` js 122 | event.toFile(); 123 | ``` 124 | 125 | Returns: 126 | 127 | ``` 128 | BEGIN:VCALENDAR 129 | VERSION:2.0 130 | PRODID:-//iCalEvent.js v0.3//EN 131 | BEGIN:VEVENT 132 | UID:d8dbbc27-7f97-4d83-9fdf-bb45d382ffdc 133 | DTSTAMP:20131208T033712 134 | DTSTART;TZID=US/Central:20140701T010000 135 | DTEND;TZID=US/Central:20140701T013000 136 | SUMMARY:Priestly Duties. 137 | DESCRIPTION:Home flu visit. 138 | ORGANIZER;CN=Nacho Libre:mailto:luchador@monastery.org 139 | LOCATION:Casa 140 | URL;VALUE=URI:http://google.com/search?q=nacho+libre 141 | END:VEVENT 142 | END:VCALENDAR 143 | ``` 144 | 145 | 146 | ## License 147 | 148 | MIT 149 | 150 | ## Todos 151 | 152 | * tests --------------------------------------------------------------------------------