Code Monkey home page Code Monkey logo

grails-ic-alender's Introduction

Grails iCalendar Plugin

Build Status

Grails Version Support

Grails 2.x

Use version 0.4.4 in Grails 2.x projects by adding it as a plugin dependency in BuildConfig.groovy.

plugins {
    ...
    compile ":ic-alendar:0.4.5"
}

Please not that the Grails 2.x plugin is end of life since 2017 and won't get any maintainance at all. To get support either upgrade to Grails 3.x or provide a pull request for the Grails 2.x plugin on branch grails2.    

Grails 3.x

Use version 0.5.0 or above for Grails 3.x projects by adding it as a dependency in build.gradle.

dependencies {
    ...
    compile "org.grails.plugins:iCalendar:0.6.1"
}

Introduction

This listing is only valid until plugin version 0.5.x

class TestController {
  def index = {

    render(contentType: 'text/calendar', filename: '<optional filename>') {
      calendar {
        events {
          event(start: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 14:00'),
                   end: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 15:00'),
                   description: 'Events description',
                   summary: 'Short info1') {
            organizer(name: 'Silvio Wangler', email: '[email protected]')
          }
          event(start: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 14:00'),
                  end: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 15:00'),
                  description: 'hell yes',
                  summary: 'Short info2',
                  location: '@home',
                  classification: 'private'){
            organizer(name: 'Silvio Wangler', email: '[email protected]')
          }
        }
      }
    }
  }
}

The Grails 3 version of the plugin starting from version 0.6.0 uses Groovy Traits to inject a render method into your controller.

// Since version 0.6.0
class TestController implements CalendarExporter {

  def index = {

    renderCalendar {
      calendar {
        events {
          event(start: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 14:00'), end: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 15:00'), description: 'Events description', summary: 'Short info1') {
            organizer(name: 'Silvio Wangler', email: '[email protected]')
          }
          event(start: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 14:00'), end: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 15:00'), description: 'hell yes', summary: 'Short info2', location: '@home', classification: 'private')
        }
      }
    }
  }
}

This plugin uses the ical4j API and is therefore iCalendar RFC compliant. The output has been tested against the Google Calendar importer, Microsoft Outlook and Mozilla Sunbird.

The plugin is at the current stage of development limited to events only. That means that you currently can only export VEVENTS.

What else can you do?

This documentation does not claim to cover all the features that are implemented in the iCalendar plugin. But there is a Unit Test Suite that covers the feature set of this plugin and therefore a very good entry point if you are looking for an overview.

Disable the plugin per controller

(Only valid up to version 0.5.x)

If you do not want to have this feature injected into every controller you can specify which controllers to be excluded in Config.groovy

grails.plugins.ical.controllers.exclude = ['excludedTest']

This Configuration parameter has to be a list of controller names!

Invite attendees

render(contentType: 'text/calendar') {
    calendar {
        events {
            event(start: new Date(), end: (new Date()).next(), summary: 'We need to talk') {
                organizer(name:"Peter O'Brien", email:'[email protected]')
                reminder(minutesBefore: 5, description: 'Your meeting starts in 5 minutes!')
                attendees {
                    attendee(email:'[email protected]', role: REQ_PARTICIPANT, partstat: NEEDS_ACTION, cutype: INDIVIDUAL, rsvp: TRUE)
                    attendee(email:'[email protected]', role: REQ_PARTICIPANT, partstat: NEEDS_ACTION, cutype: INDIVIDUAL, rsvp: FALSE)
                }
            }
        }
    }
}

Use UTC dates

Since version 0.4.0 the plugin supports UTC dates. Each event accepts an optional parameter called utc. If the parameter is missing UTC is set to false.

render(contentType: 'text/calendar') {
    calendar {
        events {
            event(
                start: new Date(), 
                end: new Date(), 
                description: 'Some large text', 
                summary: 'Project stand up meeting', 
                utc: true // optional parameter (default = false)
            )
        }
    }
}

All day events

Version 0.4.1 introduces DSL support for all day events. You can use a String by defining a date like 12.10.2014.

calendar {
    events {
        allDayEvent(date: '12.04.2013', summary: 'Text') {
            organizer(name: 'Silvio', email: '[email protected]')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}

Currently there is a limitation that the date format has to be DD.MM.YYYY. The fix of this limitation will be address in a future release.

Another way is to simply provide a Date instance

calendar {
    events {
        allDayEvent(date: new java.util.Date(), summary: 'Text') {
            organizer(name: 'Silvio', email: '[email protected]')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}

Adding X-Properties to a calendar

For some calendar clients such as Microsoft Outlook it can be useful to set vendor specific properties such as X-PRIMARY-CALENDAR. Since version 0.4.5 (for Grails 2.x) and version 0.5.1 (for Grails 3.x) you can set custom properties like this.

calendar(xproperties: ['X-WR-RELCALID': '1234', 'X-PRIMARY-CALENDAR': 'TRUE']) {
    events {
        allDayEvent(date: new java.util.Date(), summary: 'Text') {
            organizer(name: 'Silvio', email: '[email protected]')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}

grails-ic-alender's People

Contributors

dpilafian avatar ericangel avatar kgeis avatar peh avatar saw303 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

grails-ic-alender's Issues

Dependencies of ical4j:2.0.0 kill application with Spring security

New version (0.6.1) dependancies

+--- org.grails.plugins:iCalendar:0.6.1
| --- org.mnode.ical4j:ical4j:2.0.0
| +--- org.slf4j:slf4j-api:1.7.10 -> 1.7.21
| +--- org.apache.commons:commons-collections4:4.0
| +--- org.codehaus.groovy:groovy-all:2.3.2 -> 2.4.7
| +--- biz.aQute.bnd:bndlib:2.3.0
| | --- org.osgi:org.osgi.core:4.3.1
| +--- org.apache.commons:commons-lang3:3.3.2
| --- commons-codec:commons-codec:1.9

10Mb of new dependencies =)

Previous (0.6.0)

org.grails.plugins:iCalendar:0.6.0
| --- org.mnode.ical4j:ical4j:1.0.7
| +--- commons-logging:commons-logging:1.1.3 -> 1.2
| +--- commons-codec:commons-codec:1.8 -> 1.9
| +--- commons-lang:commons-lang:2.6
| --- backport-util-concurrent:backport-util-concurrent:3.1

Grails 3.1.15
The problem reproducible only on tomcat

Now I'm trying to exclude dependencies, without success.

compile ('org.grails.plugins:iCalendar:0.6.1'){
exclude group:'org.slf4j'
exclude group:'biz.aQute.bnd'
exclude group:'org.codehaus.groovy'
exclude group:'commons-codec'
}

Is it possible rollback dependencies ?

Added categories to the ICalendarBuilder.groovy

Great plugin thank you.

I needed categories compliant from (http://tools.ietf.org/html/rfc5545) for my ics files so I added a line of code to your groovy file. I was hoping you could add this in your next version.

       /*
       set internet address to null otherwise it takes awful lots of time to resolve a hostname or ip address
        */
        currentEvent.properties << new UidGenerator(null, 'iCalPlugin-Grails').generateUid()
        currentEvent.properties << tz.timeZoneId
        if (params.location) currentEvent.properties << new Location(params.location)
        if (params.description) currentEvent.properties << new Description(params.description)
        if (params.categories) currentEvent.properties << new Categories(params.categories)
        if (params.classification) currentEvent.properties << getClazz(params.classification)
        currentEvent.properties << new Organizer()
        this.cal.components << currentEvent

Example use:

event(start: Date.parse('dd.MM.yyyy HH:mm', '31.12.2013 14:00'),
    end: Date.parse('dd.MM.yyyy HH:mm', '31.12.2013 15:00'),
    description: 'Football game this Saturday',
    summary: 'Football game',
    categories: 'Football',
    location: 'Field B')
    {
        organizer(name: 'Mr Football', email: '[email protected]')
    }

Thanks again.

Extraneous notifications printing to terminal

Messages such as the following are displayed to the terminal:

Modifying render method on controller 'Account'

The messages originate from a println statement in ICalendarGrailsPlugin.groovy. Switching to a log.info statement would be cleaner.

Support for UTC export

Hi,

First of all, great plugin. Extremely useful, and easy to use.

As far as I can tell, there's no current way to export start and end event dates in UTC format. Is that right? Poking around your code and the iCal4J forums seems to indicate that to do so the "setUtc" method would need to be called on the DateTime objects.

If you know any work arounds to get this to work or alternate approaches I would love to hear about it.

Thanks again,
David

Invalid plugin error for v0.3.6

We just attempted to update to the latest version of the plugin with:

compile ":ic-alendar:0.3.6"

The grails compile command now aborts with the message:

Error Zip /Users/dpilafian/.grails/ivy-cache/org.grails.plugins/
ic-alendar/zips/ic-alendar-0.3.6.zip is not a valid plugin

The error message is not particularly informative. If there's other information that would be helpful, just let me know.

Unable to install latest releases (0.4.3 and 0.4.2)

I am unable to upgrade from 0.4.0 to releases 0.4.3 or 0.4.2. The plugins cannot be found.

Repository config:

    repositories {
        grailsPlugins()
        grailsHome()
        grailsCentral()
    }

Given:
compile ":ic-alendar:0.4.3"

Produces:

        ::::::::::::::::::::::::::::::::::::::::::::::
        ::          UNRESOLVED DEPENDENCIES         ::
        ::::::::::::::::::::::::::::::::::::::::::::::
        :: org.grails.plugins#ic-alendar;0.4.3: not found
        ::::::::::::::::::::::::::::::::::::::::::::::

Given:
compile ":ic-alendar:0.4.2"

Produces:

        ::::::::::::::::::::::::::::::::::::::::::::::
        ::          UNRESOLVED DEPENDENCIES         ::
        ::::::::::::::::::::::::::::::::::::::::::::::
        :: org.grails.plugins#ic-alendar;0.4.2: not found
        ::::::::::::::::::::::::::::::::::::::::::::::

Setting version to 0.4.0 installs fine.

I am using grails version 2.3.5

Is there a way to set the custom uid for an event ?

I cant find a way to do this, as I also want to update the events. On ICalendarBuilder.groovy:156, I see:

currentEvent.properties << new UidGenerator(null, 'iCalPlugin-Grails').generateUid()

This makes me think that it may be just hard coded. Am I right ? The idea is to update an event by setting the same uid in an event.

Can't specify an "all-day" event

Is there a way to specify that an event is all-day? I looked at your code and it seems like the start and end dat and time are getting parsed no matter what. I looked into the underlying calendar and it seems from the javadoc of ical4j that you can specify an "all-day" event by only specifying the STARTDATE on the VEvent.

I'm going to attempt a workaround by just creating a Events using the underlying calendar for my types that require all day events, but it would be nice to just do it the Groovy way with your iCalendarBuilder class.

A new UidGenerator is being created for each event causing many hostname lookups

When generating many events at a once, there is a large spike in DNS traffic. After digging through the source, I noticed that a new UidGenerate is created for each event:

currentEvent.properties << new UidGenerator('iCalPlugin-Grails').generateUid()

Looking at the constructor implementation of the net.fortuna.ical4j.util.UidGenerator, you can see that this will create a new InetAddressHostInfo each time, instead of allowing it to just use a cached copy:

    /**
     * @param pid a unique process identifier for the host machine
     * @throws SocketException where host information cannot be retrieved
     */
    public UidGenerator(String pid) throws SocketException {
        this(new InetAddressHostInfo(), pid);
    }

If the UidGenerator was created once per ICalendarBuilder, there would be far less reverse name lookups performed.

commas are rendered in a strange way

hi kindly developers,

first of all thank you for developing this great plugin.

I have the problem that if in the description or the summary (maybe somewhere else too) of an event is a comma, the output of the comma is rendered as ,

e.g.

def test() {
        renderCalendar {
            calendar {
                events {
                    event(start: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 14:00'),
                    end: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 15:00'),
                    description: 'hell, yes',
                    summary: 'Short, info2',
                    location: '@home',
                    classification: 'private'){
                        organizer(name: 'Silvio Wangler', email: '[email protected]')
                    }
                }
            }
        }
    }

is rendered as

BEGIN:VCALENDAR
PRODID:-//Grails iCalendar plugin//NONSGML Grails iCalendar plugin//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTAMP:20180108T110609Z
DTSTART;TZID=Europe/Zurich:20091101T140000
DTEND;TZID=Europe/Zurich:20091101T150000
**SUMMARY:Short\\, info2**
UID:20180108T110609Z-iCalPlugin-Grails@fe80:0:0:0:6cb2:d4ff:fe2a:3be4%awdl0
TZID:Europe/Zurich
LOCATION:@home
**DESCRIPTION:hell\\, yes**
CLASS:PRIVATE
ORGANIZER;CN=Silvio Wangler:mailto:[email protected]
METHOD:PUBLISH
END:VEVENT
END:VCALENDAR

Is this a bug or is there a way to get over it?

Kind regards
Dietmar

Modifying render method on controller ...

Is there any way to restrict the activation of this plugin to only the controllers where we need it? We are seeing in the log that it is modifying every render on every controller.

DTSTART and DTEND do not have their TZID property set

DTSTART and DTEND do not have their TZID property set when a timezone is provided.

Expected:

DTSTART;TZID=America/Toronto:20150201T090000
DTEND;TZID=America/Toronto:20150201T090000

Actual:

DTSTART:20150201T090000
DTEND:20150201T090000

Cause:
The date instances are created with the DateTime(String value, String pattern, TimeZone timezone) constructor and passed a timezone, but this timezone is not assigned to the DateTime instance's timezone property:

From ICalendarBuilder.groovy:

private void handleEventNode(Map params, nodeName) {
    ...

    def startDate = new DateTime(params.start.format(dateFormat), dateFormat, timezone)
    def endDate = new DateTime(params.end.format(dateFormat), dateFormat, timezone)

    startDate.setUtc(isUtc)
    endDate.setUtc(isUtc)

    currentEvent = new VEvent(startDate, endDate, params.summary)

    ...

From iCal4j:

    public DateTime(String value, String pattern, TimeZone timezone)
            throws ParseException {
        // setting the time to 0 since we are going to reset it anyway
        super(0, Dates.PRECISION_SECOND, timezone != null ? timezone
                : java.util.TimeZone.getDefault());
        this.time = new Time(getTime(), getFormat().getTimeZone());

        final DateFormat format = CalendarDateFormatFactory
                .getInstance(pattern);
        setTime(value, format, timezone);
    }

If you explicitly set the timezone then the TZID property gets added to DTEND AND DTSTART:

    startDate.setTimeZone(timezone);
    endDate.setTimeZone(timezone);

Suggested from the iCal4j documentation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.