Skip to content

Commit

Permalink
LSNBLDR-711 Added Twitter Timeline component for lessons (sakaiprojec…
Browse files Browse the repository at this point in the history
…t#3659)

LSNBLDR-711: Twitter Timeline component for lessons

LSNBLDR-711 Added Twitter Timeline component for lessons

LSNBLDR-711: Twitter Timeline component for lessons

Conflicts:
	lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java
	lessonbuilder/tool/src/webapp/templates/ShowPage.html

LSNBLDR-711: brian's PR comment

Conflicts:
	lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java
	lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/producers/ShowPageProducer.java
	lessonbuilder/tool/src/webapp/templates/ShowPage.html

LSNBLDR-711: Added Twitter Timeline component for lessons

LSNBLDR-711: Improve explanation of proeprty
  • Loading branch information
nicholaswilson100 authored and adrianfish committed Mar 15, 2017
1 parent 28989da commit 2bf3346
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4683,6 +4683,17 @@
#default is empty, so all groups are collapsed by default
#sitemanage.tools.groups.expanded=systoolgroups.lti


# ######################################################
# LSNBLDR-711 Added Twitter Timeline component for lessons
# ######################################################
# This is the Twitter widget id (used in the Lessons tool) which varies for each institution.
# It is used by the Twitter widget in Lessons to access the Twitter API and
# grab the widget HTML. To find out what your widget id is, go to https://twitter.com/settings/widgets,
# edit your widget (or create one if you don't have one), and the id (a long number) is the value of "data-widget-id"
# in the embed code bottom right.
#lessonbuilder.twitter.widget.id=123456789012345678

#SAK-25438 - Zip Download in Resources
#Option is not available unless the next properties are configured with a value (in bytes) greater than 0.
#Max size in bytes for a single file - Default 0 bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.text.SimpleDateFormat;
import java.text.Format;
import java.math.BigDecimal;

import org.apache.commons.lang.StringUtils;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -149,6 +151,7 @@ public enum Status {
public static final String LESSONBUILDER_BACKPATH = "lessonbuilder.backpath";
public static final String LESSONBUILDER_ID = "sakai.lessonbuildertool";
public static final String CALENDAR_TOOL_ID = "sakai.schedule";
public static final String TWITTER_WIDGET_DEFAULT_HEIGHT = "300";
public static final String ANNOUNCEMENTS_TOOL_ID = "sakai.announcements";
public static final String FORUMS_TOOL_ID = "sakai.forums";

Expand Down Expand Up @@ -305,7 +308,10 @@ public enum Status {
//variables used for announcements widget
private String announcementsHeight;
private String announcementsDropdown;

//variables used for twitter setting used in the widget
private String twitterDropDown;
private String twitterUsername;
private String twitterWidgetHeight;
// almost ISO format. real thing can't be done until Java 7. uses -0400 rather than -04:00
// SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
SimpleDateFormat isoDateFormat = getIsoDateFormat();
Expand Down Expand Up @@ -915,6 +921,9 @@ public void setMimetype(String mimetype) {
mimetype = mimetype.toLowerCase().trim();
this.mimetype = mimetype;
}
public void setTwitterDropDown(String twitterDropDown) {
this.twitterDropDown = twitterDropDown;
}

public String getPageTitle() {
return getCurrentPage().getTitle();
Expand Down Expand Up @@ -990,6 +999,14 @@ public void setAnnouncementsDropdown(String announcementsDropdown) {
this.announcementsDropdown = announcementsDropdown;
}

public void setTwitterUsername(String twitterUsername) {
this.twitterUsername = twitterUsername;
}

public void setTwitterWidgetHeight(String twitterWidgetHeight) {
this.twitterWidgetHeight = twitterWidgetHeight;
}

// hibernate interposes something between us and saveItem, and that proxy gets an
// error after saveItem does. Thus we never see any value that saveItem might
// return. Hence we pass saveItem a list to which it adds the error message. If
Expand Down Expand Up @@ -3455,6 +3472,7 @@ public String getReleaseString(SimplePageItem i, Locale locale) {
&& i.getType() != SimplePageItem.BLTI
&& i.getType() != SimplePageItem.COMMENTS
&& i.getType() != SimplePageItem.QUESTION
&& i.getType() != SimplePageItem.TWITTER
&& i.getType() != SimplePageItem.BREAK
&& i.getType() != SimplePageItem.STUDENT_CONTENT) {
Object cached = groupCache.get(i.getSakaiId());
Expand Down Expand Up @@ -3496,6 +3514,7 @@ public String getReleaseString(SimplePageItem i, Locale locale) {
case SimplePageItem.PAGE:
case SimplePageItem.COMMENTS:
case SimplePageItem.QUESTION:
case SimplePageItem.TWITTER:
case SimplePageItem.STUDENT_CONTENT:
return getLBItemGroups(i); // for all native LB objects
default:
Expand Down Expand Up @@ -3728,6 +3747,7 @@ public List<String> setItemGroups (SimplePageItem i, String[] groups) {
case SimplePageItem.PAGE:
case SimplePageItem.BLTI:
case SimplePageItem.COMMENTS:
case SimplePageItem.TWITTER:
case SimplePageItem.QUESTION:
case SimplePageItem.STUDENT_CONTENT:
return setLBItemGroups(i, groups);
Expand Down Expand Up @@ -8523,10 +8543,9 @@ public static String utf8truncate(String input, int length) {
* To add latest conversations in a div on Lessons Page
*/
public String addForumSummary(){
if (!itemOk(itemId))
return "permission-failed";
if (!checkCsrf())
if (!itemOk(itemId) || !checkCsrf()) {
return "permission-failed";
}
String status = "success";
if (canEditPage()) {
SimplePageItem item;
Expand Down Expand Up @@ -8618,4 +8637,46 @@ public String addCalendar(String ab){
}
return result;
}
/**
* To add twitter timeline with given parameters in a Lessons page
*/
public String addTwitterTimeline(){
if (!itemOk(itemId) || !checkCsrf()){
return "permission-failed";
}
//if username is not provided return
if(StringUtils.isBlank(twitterUsername)){
return "failure";
}
//Check if height is supplied if not then set to default
if(StringUtils.isBlank(twitterWidgetHeight)){
twitterWidgetHeight = TWITTER_WIDGET_DEFAULT_HEIGHT;
}
//if user has added @ symbol with the username, remove it
if( twitterUsername.contains("@")){
twitterUsername = StringUtils.remove(twitterUsername, "@");
}
String status = "success";
if (canEditPage()) {
SimplePageItem item;
// itemid -1 means we're adding a new item to the page,
// specified itemid means we're updating an existing one
if (itemId != null && itemId != -1) {
item = findItem(itemId);
} else {
item = appendItem("", "", SimplePageItem.TWITTER);
}
//setting height , username and number of tweets as attributes for the twitter item.
item.setAttribute("height", twitterWidgetHeight);
item.setAttribute("username", twitterUsername);
item.setAttribute("numberOfTweets", twitterDropDown );
item.setPrerequisite(this.prerequisite);
setItemGroups(item, selectedGroups);
update(item);

} else {
status = "cancel";
}
return status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sakaiproject.component.cover.ComponentManager;
Expand Down Expand Up @@ -226,6 +227,8 @@ public void setImageToMimeMap(Map<String,String> map) {
private static final String DEFAULT_WIDTH = "640px";
// almost ISO. Full ISO isn't available until Java 7. this uses -0400 where ISO uses -04:00
SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
//institution's twitter widget id, should come from properties file
public static final String TWITTER_WIDGET_ID = "lessonbuilder.twitter.widget.id";

// WARNING: this must occur after memoryService, for obvious reasons.
// I'm doing it this way because it doesn't appear that Spring can do this kind of initialization
Expand Down Expand Up @@ -1244,7 +1247,7 @@ public int compare(SimpleStudentPage o1, SimpleStudentPage o2) {
|| i.getType() == SimplePageItem.QUESTION || i.getType() == SimplePageItem.PEEREVAL || i.getType() == SimplePageItem.RESOURCE_FOLDER
|| i.getType() == SimplePageItem.CHECKLIST || i.getType() == SimplePageItem.FORUM_SUMMARY
|| i.getType() == SimplePageItem.BREAK || i.getType() == SimplePageItem.ANNOUNCEMENTS
|| i.getType() == SimplePageItem.CALENDAR );
|| i.getType() == SimplePageItem.CALENDAR || i.getType() == SimplePageItem.TWITTER );
// (i.getType() == SimplePageItem.PAGE &&
// "button".equals(i.getFormat())))

Expand Down Expand Up @@ -1276,6 +1279,7 @@ public int compare(SimpleStudentPage o1, SimpleStudentPage o2) {
case SimplePageItem.BLTI: itemClassName = "bltiType"; break;
case SimplePageItem.RESOURCE_FOLDER: itemClassName = "resourceFolderType"; break;
case SimplePageItem.PEEREVAL: itemClassName = "peereval"; break;
case SimplePageItem.TWITTER: itemClassName = "twitter"; break;
case SimplePageItem.FORUM_SUMMARY: itemClassName = "forumSummary"; break;
case SimplePageItem.ANNOUNCEMENTS: itemClassName = "announcementsType"; break;
case SimplePageItem.CALENDAR: itemClassName = "calendar"; break;
Expand Down Expand Up @@ -3254,7 +3258,46 @@ else if(questionStatus == Status.FAILED)
}

makeSaveChecklistForm(tofill);
} else {
}else if(i.getType() == SimplePageItem.TWITTER) {
UIOutput.make(tableRow, "twitterSpan");
String itemGroupString = null;
String itemGroupTitles = null;
if (canSeeAll) {
itemGroupString = simplePageBean.getItemGroupString(i, null, true);
if (itemGroupString != null)
itemGroupTitles = simplePageBean.getItemGroupTitles(itemGroupString, i);
if (itemGroupTitles != null) {
itemGroupTitles = "[" + itemGroupTitles + "]";
}
if (canEditPage)
UIOutput.make(tableRow, "item-groups", itemGroupString);
if (itemGroupTitles != null)
UIOutput.make(tableRow, "twitter-groups-titles", itemGroupTitles);
}
if(canSeeAll || simplePageBean.isItemAvailable(i)) {
//Getting variables from attributes of this twitter page item
String tweetLimit = i.getAttribute("numberOfTweets") != null ? i.getAttribute("numberOfTweets") : "5";
String height = i.getAttribute("height") != null ? i.getAttribute("height") : "" ;
String username = i.getAttribute("username") != null ? i.getAttribute("username") : "";

String href = "https://twitter.com/" + StringUtils.trim(username);
String divHeight = "height:" + height + "px;";
//Note: widget id used is from uni's twitter account
String html = "<div align=\"left\" style='"+divHeight+"' class=\"twitter-div\"><a class=\"twitter-timeline\" href= '" +href+ "' data-widget-id='" +ServerConfigurationService.getString(TWITTER_WIDGET_ID)+ "' data-tweet-limit='" +tweetLimit +"' data-dnt=\"true\" data-screen-name='" +username+"'>Tweets by @'" +username+"'</a></div>";
UIVerbatim.make(tableRow, "content", html);
UIOutput.make(tableRow, "username", username);
UIOutput.make(tableRow, "tweetLimit", tweetLimit);
UIOutput.make(tableRow, "twitter-height", height);
UIOutput.make(tableRow, "twitterId", String.valueOf(i.getId()));
} else {
UIComponent unavailableText = UIOutput.make(tableRow, "content", messageLocator.getMessage("simplepage.textItemUnavailable"));
unavailableText.decorate(new UIFreeAttributeDecorator("class", "disabled-text-item"));
}
if (canEditPage) {
UIOutput.make(tableRow, "twitter-td");
UILink.make(tableRow, "edit-twitter", (String) null, "");
}
} else {
// remaining type must be a block of HTML
UIOutput.make(tableRow, "itemSpan");

Expand Down Expand Up @@ -3402,6 +3445,7 @@ public void createDialogs(UIContainer tofill, SimplePage currentPage, SimplePage
createCommentsDialog(tofill);
createStudentContentDialog(tofill, currentPage);
createQuestionDialog(tofill, currentPage);
createTwitterDialog(tofill, currentPage);
createForumSummaryDialog(tofill, currentPage);
createDeleteItemDialog(tofill, currentPage);
createAnnouncementsDialog(tofill, currentPage);
Expand Down Expand Up @@ -3769,7 +3813,27 @@ private static String getUserDisplayName(String owner) {
return user.getDisplayName();
}

private static void disableLink(UIComponent link, MessageLocator messageLocator) {
//Get the twitter widget hashtag and other settings from the user.
private void createTwitterDialog(UIContainer tofill, SimplePage currentPage) {
UIOutput.make(tofill, "add-twitter-dialog").decorate(new UIFreeAttributeDecorator("title", messageLocator.getMessage("simplepage.twitter")));
UIForm form = UIForm.make(tofill, "add-twitter-form");
makeCsrf(form, "csrf13");
UIInput.make(form, "twitterEditId", "#{simplePageBean.itemId}");
UIInput.make(form, "twitter-addBefore", "#{simplePageBean.addBefore}");
UIInput.make(form, "twitter-username", "#{simplePageBean.twitterUsername}");
UIOutput.make(form, "twitter-username-label", messageLocator.getMessage("simplepage.twitter-username"));
UIInput.make(form, "widget-height", "#{simplePageBean.twitterWidgetHeight}");
UIOutput.make(form, "height-label", messageLocator.getMessage("simplepage.twitter.height_label"));
//Adding default values for tweet number dropdown
String[] options = {"5","10","25","50","100","1000"};
String[] labels = {"5","10","25","50","100","1000"};
UIOutput.make(form, "numberDropdownLabel", messageLocator.getMessage("simplepage.number-dropdown-label"));
UISelect.make(form, "numberDropdown", options, labels, "#{simplePageBean.twitterDropDown}","5");
UICommand.make(form, "twitter-add-item", messageLocator.getMessage("simplepage.save_message"), "#{simplePageBean.addTwitterTimeline}");
UICommand.make(form, "twitter-cancel", messageLocator.getMessage("simplepage.cancel"), null);
UICommand.make(form, "delete-twitter-item", messageLocator.getMessage("simplepage.delete"), "#{simplePageBean.deleteItem}");
}
private static void disableLink(UIComponent link, MessageLocator messageLocator) {
link.decorate(new UIFreeAttributeDecorator("onclick", "return false"));
link.decorate(new UIDisabledDecorator());
link.decorate(new UIStyleDecorator("disabled"));
Expand Down Expand Up @@ -4028,6 +4092,10 @@ private void createToolBar(UIContainer tofill, SimplePage currentPage, boolean i
makeCsrf(form, "csrf26");
UICommand.make(form, "add-student", "#{simplePageBean.addStudentContentSection}");

//Adding 'Embed twitter timeline' component
UIOutput.make(tofill, "twitter-li");
UILink twitterLink = UIInternalLink.makeURL(tofill, "add-twitter", "#");
twitterLink.decorate(new UITooltipDecorator(messageLocator.getMessage("simplepage.twitter-descrip")));
// in case we're on an old system without current BLTI
if (bltiEntity != null && ((BltiInterface)bltiEntity).servicePresent()) {
Collection<BltiTool> bltiTools = simplePageBean.getBltiTools();
Expand Down
7 changes: 7 additions & 0 deletions lessonbuilder/tool/src/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ simplepage.pagehidden=You have checked the 'Hide' box in the Settings window. Th
simplepage.pagehidden.text=<strong>Note:</strong> This page is currently hidden from standard users. You can change this in the <strong>Settings</strong> window.
simplepage.showallpages=Index of pages
simplepage.adding-text=Adding text to:
simplepage.twitter=Embed Twitter Timeline
simplepage.twitter-descrip=Add a twitter feed to this page, e.g. departmental, subject or personal.
simplepage.twitter-username=Twitter Username, e.g. @OxfordWebLearn
simplepage.number-dropdown-label=Number of Tweets:
simplepage.twitter-name-notblank=Please supply username.
simplepage.edit-title.twitter=Edit Twitter timeline
simplepage.twitter.height_label=Height of display box (in pixels)

simplepage.continue=Continue

Expand Down
4 changes: 4 additions & 0 deletions lessonbuilder/tool/src/webapp/WEB-INF/applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ simplePageBean.addAnnouncements,
simplePageBean.peerEval,
simplePageBean.peerEvalDueDate,
simplePageBean.peerEvalOpenDate,
simplePageBean.twitterDropDown,
simplePageBean.twitterUsername,
simplePageBean.twitterWidgetHeight,
simplePageBean.addTwitterTimeline,
simplePageBean.peerEvalAllowSelfGrade,
simplePageBean.folderPickerSubmit,
simplePageBean.folderPath,
Expand Down
24 changes: 17 additions & 7 deletions lessonbuilder/tool/src/webapp/css/Simplepagetool.css
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
make them subjectively the same darkness.
*/
/* default */
.column .commentDiv, .column .studentContentTable, .column .questionDiv .contentCol, .column .checklistDiv, .column .forumSummaryHeaderDiv, .column .announcementsHeaderDiv, .column .fc-toolbar {
.column .commentDiv, .column .studentContentTable, .column .questionDiv .contentCol, .column .checklistDiv, .column .forumSummaryHeaderDiv, .column .announcementsHeaderDiv, .column .fc-toolbar .timeline-Header{
background-color: #b3ecff;
}
.column a[href]{
Expand All @@ -482,7 +482,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
background-color: #f0f0f0;
border-color: #222;
}
.colgray .commentDiv, .colgray .studentContentTable, .colgray .questionDiv .contentCol, .colgray .checklistDiv, .colgray .forumSummaryHeaderDiv, .colgray .announcementsHeaderDiv, .colgray .fc-toolbar {
.colgray .commentDiv, .colgray .studentContentTable, .colgray .questionDiv .contentCol, .colgray .checklistDiv, .colgray .forumSummaryHeaderDiv, .colgray .announcementsHeaderDiv .timeline-Header{
background-color: #b8b8b8;
}
.colgray a[href]{
Expand All @@ -493,7 +493,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
border-color: #600;
color: #4660000;
}
.colred .commentDiv, .colred .studentContentTable, .colred .questionDiv .contentCol, .colred .checklistDiv, .colred .forumSummaryHeaderDiv, .colred .announcementsHeaderDiv, .colred .fc-toolbar {
.colred .commentDiv, .colred .studentContentTable, .colred .questionDiv .contentCol, .colred .checklistDiv, .colred .forumSummaryHeaderDiv, .colred .announcementsHeaderDiv .timeline-Header{
background-color: #ffb3b3;
}
.colred a[href], .colred h3.author {
Expand All @@ -505,7 +505,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
border-color: #004;
color: #004;
}
.colblue .commentDiv, .colblue .studentContentTable, .colblue .questionDiv .contentCol, .colblue .checklistDiv, .colblue .forumSummaryHeaderDiv, .colblue .announcementsHeaderDiv, .colblue .fc-toolbar {
.colblue .commentDiv, .colblue .studentContentTable, .colblue .questionDiv .contentCol, .colblue .checklistDiv, .colblue .forumSummaryHeaderDiv, .colblue .announcementsHeaderDiv .timeline-Header{
background-color: #b3d9ff;
background-color: #99e7ff;
}
Expand All @@ -517,7 +517,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
border-color: #030;
color: #030;
}
.colgreen .commentDiv, .colgreen .studentContentTable, .colgreen .questionDiv .contentCol, .colgreen .checklistDiv. .colgreen .forumSummaryHeaderDiv, .colgreen .announcementsHeaderDiv, .colgreen .fc-toolbar {
.colgreen .commentDiv, .colgreen .studentContentTable, .colgreen .questionDiv .contentCol, .colgreen .checklistDiv. .colgreen .forumSummaryHeaderDiv, .colgreen .announcementsHeaderDiv .timeline-Header{
background-color: #9fc;
}
.colgreen a[href] {
Expand All @@ -528,7 +528,7 @@ a.edit-link:link, a.edit-link:visited, a.section-merge-link:link, a.section-merg
border-color: #840;
color: #4b2600;
}
.colyellow .commentDiv, .colyellow .studentContentTable, .colyellow .questionDiv .contentCol, .colyellow .checklistDiv. colyellow .forumSummaryHeaderDiv, .colyellow .announcementsHeaderDiv, .colyellow .fc-toolbar {
.colyellow .commentDiv, .colyellow .studentContentTable, .colyellow .questionDiv .contentCol, .colyellow .checklistDiv. colyellow .forumSummaryHeaderDiv, .colyellow .announcementsHeaderDiv .timeline-Header{
background-color: #ffd480
}
.colyellow a[href],.colyellow h3.author {
Expand Down Expand Up @@ -1149,7 +1149,17 @@ img {
margin-bottom: 0.5em;
margin-top: 0em;
}

.twitter-div{
overflow-y: auto;
float: left;margin:
0 10.0px 20.0px 0;
border: solid #999 1px;
border-radius: 0px 0px 10px 10px;
clear: right;
}
.edit-twitter-div{
float:left;
}
#question-text-input {
width: 400px;
}
Expand Down
Loading

0 comments on commit 2bf3346

Please sign in to comment.