Skip to content

Commit

Permalink
Merge iCal Dashlet trunk to branches/1.0 and update version to 0.2
Browse files Browse the repository at this point in the history
 - Title set to 'Untitled Calendar' for feeds missing title and description
 - Support for Surf connectors using scheme remote:connectorName/path/to/asset
 - Config bar now hidden for non-admins in a site

git-svn-id: https://share-extras.googlecode.com/svn/branches/1.0/iCal Feed Dashlet@1274 a3f5c567-fd0f-3a89-9b71-a290c5a5f590
  • Loading branch information
wabson committed Aug 9, 2012
1 parent b8556bc commit 9af3f8d
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 127 deletions.
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
jar.name=ical-feed-dashlet.jar
jar.name=ical-feed-dashlet-0.2.jar
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

<div class="dashlet ical-feed-dashlet">
<div class="title" id="${args.htmlid}-title"></div>
<#if hasConfigPermission>
<div class="toolbar">
<a id="${args.htmlid}-config-link" class="theme-color-1" href="#">${msg("link.configure")}</a>
</div>
</#if>
<div class="body scrollableList" id="${args.htmlid}-body" <#if args.height??>style="height: ${args.height}px;"</#if>>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
function main()
{
var hasConfigPermission = false;

// Work out if the user has permission to configure the dashlet

if (page.url.templateArgs.site != null) // Site or user dashboard?
{
// Call the repository to see if the user is a site manager or not
var obj = context.properties["memberships"];
if (!obj)
{
var json = remote.call("/api/sites/" + page.url.templateArgs.site + "/memberships/" + stringUtils.urlEncode(user.name));
if (json.status == 200)
{
obj = eval('(' + json + ')');
}
}
if (obj)
{
hasConfigPermission = (obj.role == "SiteManager");
}
}
else
{
hasConfigPermission = true; // User dashboard
}

model.hasConfigPermission = hasConfigPermission;
}

main();
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
label.title=iCalendar Feed
label.title-feed={0}
label.untitled=Untitled Calendar
msg.not-configured=No Feed URL has been specified
msg.error=An error occurred while attempting to fetch the iCal feed
msg.no-events=No upcoming events were found
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,162 +4,200 @@ function main()
var component = sitedata.getComponent(url.templateArgs.componentId);
if (component != null)
{
var feedUrl = component.properties.feedUrl;
var feedUrl = component.properties.feedUrl, connectorName = "http";

if (feedUrl != null && feedUrl.indexOf("http") == 0)
if (!feedUrl)
{
var connector = remote.connect("http"),
result = connector.get(feedUrl);

if (result.status == 200)
status.setCode(status.STATUS_BAD_REQUEST, "No valid Feed URL was found");
status.redirect = true;
return;
}
else
{
var reobj = /(\w+):(.+)/.exec(feedUrl);
if (reobj)
{
var lines = ("" + result.response).split(/\s*[\r\n]+\s*/), li, parts;
var events = [], currEvent = null, calName = null, calDesc = null;
for (var i = 0; i < lines.length; i++)
var protocol = reobj[1], locator = reobj[2];
if (protocol == "http" || protocol == "https")
{
// Do nothing
}
else if (protocol == "remote")
{
li = lines[i];
parts = li.split(":");

if (parts.length >= 2)
var locreobj = /(\w+)\/(.+)/.exec(locator);
if (locreobj)
{
if (parts[0] == "X-WR-CALNAME")
{
calName = parts[1];
}
else if (parts[0] == "X-WR-CALDESC")
{
calDesc = parts[1];
}
else if (li == "BEGIN:VEVENT")
{
currEvent = {};
}
else if (parts[0].indexOf("DTSTART") == 0)
connectorName = locreobj[1];
feedUrl = (/^https?:\/\//.exec(locreobj[2]) ? "" : "/") + locreobj[2];
}
else
{
status.setCode(status.STATUS_BAD_REQUEST, "No valid Feed URL was found - no valid endpoint name specified");
status.redirect = true;
return;
}
}
else
{
status.setCode(status.STATUS_BAD_REQUEST, "No valid Feed URL was found - bad protocol " + protocol);
status.redirect = true;
return;
}
}
else
{
status.setCode(status.STATUS_BAD_REQUEST, "No valid Feed URL was found");
status.redirect = true;
return;
}
}

var connector = remote.connect(connectorName),
result = connector.get(feedUrl);

if (result.status == 200)
{
var lines = ("" + result.response).split(/\s*[\r\n]+\s*/), li, parts;
var events = [], currEvent = null, calName = null, calDesc = null;
for (var i = 0; i < lines.length; i++)
{
li = lines[i];
parts = li.split(":");

if (parts.length >= 2)
{
if (parts[0] == "X-WR-CALNAME")
{
calName = parts[1];
}
else if (parts[0] == "X-WR-CALDESC")
{
calDesc = parts[1];
}
else if (li == "BEGIN:VEVENT")
{
currEvent = {};
}
else if (parts[0].indexOf("DTSTART") == 0)
{
if (currEvent != null)
{
if (currEvent != null)
// Datetime format, e.g. 19980119T070000Z
if (/^\d{8}T\d{6}Z$/.test(parts[1]))
{
// Datetime format, e.g. 19980119T070000Z
if (/^\d{8}T\d{6}Z$/.test(parts[1]))
{
currEvent.dtstart = {
type: "date-time",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8), //day
parts[1].substring(9,11), //hour
parts[1].substring(11,13), //minute
parts[1].substring(13,15) //second
)};
}
// Date format, e.g. 19980119
else if (/^\d{8}$/.test(parts[1]))
{
currEvent.dtstart = {
type: "date",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8) //day
)};
}
currEvent.dtstart = {
type: "date-time",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8), //day
parts[1].substring(9,11), //hour
parts[1].substring(11,13), //minute
parts[1].substring(13,15) //second
)};
}
}
else if (parts[0].indexOf("DTEND") == 0)
{
if (currEvent != null)
// Date format, e.g. 19980119
else if (/^\d{8}$/.test(parts[1]))
{
// Datetime format, e.g. 19980119T070000Z
if (/^\d{8}T\d{6}Z$/.test(parts[1]))
{
currEvent.dtend = {
type: "date-time",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8), //day
parts[1].substring(9,11), //hour
parts[1].substring(11,13), //minute
parts[1].substring(13,15) //second
)};
}
// Date format, e.g. 19980119
else if (/^\d{8}$/.test(parts[1]))
{
currEvent.dtend = {
type: "date",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8) //day
)};
}
currEvent.dtstart = {
type: "date",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8) //day
)};
}
}
else if (parts[0] == "SUMMARY")
}
else if (parts[0].indexOf("DTEND") == 0)
{
if (currEvent != null)
{
if (currEvent != null)
// Datetime format, e.g. 19980119T070000Z
if (/^\d{8}T\d{6}Z$/.test(parts[1]))
{
currEvent.summary = parts[1];
currEvent.dtend = {
type: "date-time",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8), //day
parts[1].substring(9,11), //hour
parts[1].substring(11,13), //minute
parts[1].substring(13,15) //second
)};
}
}
else if (parts[0] == "LOCATION")
{
if (currEvent != null)
// Date format, e.g. 19980119
else if (/^\d{8}$/.test(parts[1]))
{
currEvent.location = parts[1];
currEvent.dtend = {
type: "date",
value: new Date(parts[1].substring(0,4), //year
parts[1].substring(4,6) - 1, //month 0-11
parts[1].substring(6,8) //day
)};
}
}
else if (parts[0] == "UID")
}
else if (parts[0] == "SUMMARY")
{
if (currEvent != null)
{
if (currEvent != null)
{
currEvent.uid = parts[1];
}
currEvent.summary = parts[1];
}
else if (parts[0] == "URL")
}
else if (parts[0] == "LOCATION")
{
if (currEvent != null)
{
if (currEvent != null)
{
currEvent.url = parts[1] + ":" + parts[2];
}
currEvent.location = parts[1];
}
else if (parts[0] == "DTSTAMP")
}
else if (parts[0] == "UID")
{
if (currEvent != null)
{
if (currEvent != null)
{
currEvent.dtstamp = parts[1];
}
currEvent.uid = parts[1];
}
}
else if (parts[0] == "URL")
{
if (currEvent != null)
{
currEvent.url = parts[1] + ":" + parts[2];
}
}
else if (parts[0] == "DTSTAMP")
{
if (currEvent != null)
{
currEvent.dtstamp = parts[1];
}
else if (li == "END:VEVENT")
}
else if (li == "END:VEVENT")
{
if (currEvent != null)
{
if (currEvent != null)
if (currEvent.dtstart &&
currEvent.dtend && currEvent.dtend.value.getTime() > Date.now())
{
if (currEvent.dtstart &&
currEvent.dtend && currEvent.dtend.value.getTime() > Date.now())
{
events.push(currEvent);
}
currEvent = null;
events.push(currEvent);
}
currEvent = null;
}
}
}

// Parse the iCal data
model.calendar = {
name: calName,
description: calDesc
};
model.events = events;
model.calData = result.response;
}
else
{
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Error during remote call. " +
"Status: " + result.status + ", Response: " + result.response);
status.redirect = true;
}

// Parse the iCal data
model.calendar = {
name: calName,
description: calDesc
};
model.events = events;
model.calData = result.response;
}
else
{
status.setCode(status.STATUS_BAD_REQUEST, "No valid Feed URL was found");
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Error during remote call. " +
"Status: " + result.status + ", Response: " + result.response);
status.redirect = true;
}
}
Expand Down
5 changes: 5 additions & 0 deletions source/web/components/dashlets/ical-feed.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.dashlet.ical-feed-dashlet .body > div
{
padding-left: 8px;
padding-right: 8px;
}
Loading

0 comments on commit 9af3f8d

Please sign in to comment.