namespace TamTam.SharePoint2010.Social {
#region [ Usings ]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.Office.Server.ActivityFeed;
using Microsoft.SharePoint;
using System.ServiceModel.Syndication;
using System.Xml;
#endregion
///
/// Activity Feed gatherer and downloader for Twitter
///
public class TwitterActivityFeed {
#region [ Consts ]
private const string TwitterProfileField = "TwitterAccountName";
private const string ActivityApplicationName = "Twitter";
private const string ActivityTypeName = "Tweet";
#endregion
///
/// Check if a UserProfile is Twitter enabled!
///
/// the userprofile to check
/// true if the user has a twitter account filled in his profile
public static bool ProfileHasTwitter(UserProfile profile) {
bool result = false;
if ( profile != null){
if ( profile[TwitterProfileField] != null ){
if ( !string.IsNullOrEmpty(profile[TwitterProfileField].Value as string)){
result = true;
}
}
}
return result;
}
///
/// Register the ActivityApplication Twitter to the Portal(SPSite)'s User Profile Application
///
/// portal/context
public static void RegisterTwitterActivityApplication(SPSite site) {
UserProfileManager upm = new UserProfileManager(SPServiceContext.GetContext(site));
UserProfile user = upm.GetUserProfile(true);
ActivityManager am = new ActivityManager(user, SPServiceContext.GetContext(site));
if (am.PrepareToAllowSchemaChanges()) {
ActivityApplication twitterApp = am.ActivityApplications["Twitter"];
if (twitterApp == null) {
twitterApp = am.ActivityApplications.Create("Twitter");
twitterApp.Commit();
}
ActivityType tweet = twitterApp.ActivityTypes["Tweet"];
if (tweet == null) {
tweet = twitterApp.ActivityTypes.Create("Tweet");
tweet.ActivityTypeNameLocStringResourceFile = twitterApp.ApplicationName;
tweet.ActivityTypeNameLocStringName = "ActivityName";
tweet.IsPublished = true;
tweet.IsConsolidated = true;
tweet.AllowRollup = true;
tweet.Commit();
}
ActivityTemplate tweetTemplate = tweet.ActivityTemplates[ActivityTemplatesCollection.CreateKey(false)];
if (tweetTemplate == null) {
tweetTemplate = tweet.ActivityTemplates.Create(false);
tweetTemplate.TitleFormatLocStringResourceFile = twitterApp.ApplicationName;
tweetTemplate.TitleFormatLocStringName = "Activity_Tweet";
tweetTemplate.Commit();
}
}
}
///
/// Import the Twitter updates for a UserProfile and
/// publish them to the activity feed.
///
/// Portal/context
/// the user profile to import twitter updates for
/// nr of items published
public static int Import(SPSite site, UserProfile profile) {
int result = 0;
if (ProfileHasTwitter(profile)) {
// user should have a value in his profile:
string twitterUserName = profile[TwitterActivityFeed.TwitterProfileField].Value as string;
if (!string.IsNullOrEmpty(twitterUserName)) {
// activity manager to the social stuff
ActivityManager am = new ActivityManager(profile, SPServiceContext.GetContext(site));
// twitter
ActivityType tweet = am.ActivityTypes[TwitterActivityFeed.ActivityTypeName];
// last twitter update was on:
DateTime twitterLatestItem = SocialUpdateStatusList.GetLastItemDateTime(site, tweet, profile);
string newTwitterLastId = null;
// download the user's timeline as RSS feed
using (XmlReader reader = XmlReader.Create(
string.Format("http://twitter.com/statuses/user_timeline/{0}.rss", twitterUserName))) {
// convert download to a SyndicationFeed
SyndicationFeed twitterfeed = SyndicationFeed.Load(reader);
// order them the correct way
twitterfeed.Items.OrderByDescending(item => item.PublishDate);
List items = new List();
// loop through the RSS feed items
foreach (SyndicationItem item in twitterfeed.Items) {
// item is newer then the last one we published
if (item.PublishDate.DateTime > twitterLatestItem) {
// store the newest update for later on!
if (newTwitterLastId == null) {
newTwitterLastId = item.Id;
SocialUpdateStatusList.SetLastItemId(site, tweet, profile, newTwitterLastId);
}
// make the data complete
if (item.LastUpdatedTime.DateTime <= DateTime.MinValue)
item.LastUpdatedTime = item.PublishDate;
// store the twitter update to the user's activity feed
ActivityEvent activityEvent = TwitterActivityFeed.GenerateActivityEvent(am, profile, tweet, item);
items.Add(activityEvent);
}
else {
break;
}
}
// publish all the udates to collegueas and such
TwitterActivityFeed.MulticastPublishedEvents(am, items);
am.Dispose();
result = items.Count;
}
}
}
return result;
}
///
/// Generate a Activity Event based on a RSS Feed item
///
///
///
///
///
///
internal static ActivityEvent GenerateActivityEvent(ActivityManager am,UserProfile profile,ActivityType atype,SyndicationItem item) {
ActivityEvent activityEvent = null;
if (am != null) {
if (atype != null && profile != null) {
long atid = atype.ActivityTypeId;
if (item != null) {
Entity owner = new MinimalPerson(profile).CreateEntity(am);
Entity publisher = new MinimalPerson(profile).CreateEntity(am);
activityEvent = ActivityEvent.CreateActivityEvent(am, atid, owner, publisher);
activityEvent.ItemPrivacy = (int)Privacy.Public;
activityEvent.Name = atype.ActivityTypeName;
activityEvent.Owner = owner;
activityEvent.Publisher = publisher;
activityEvent.PublishDate = item.LastUpdatedTime.DateTime;
activityEvent.LastUpdateTime = item.LastUpdatedTime.DateTime;
if (item.Links.Count > 0) {
activityEvent.Link = new Link();
activityEvent.Link.Href = item.Links[0].Uri.AbsoluteUri;
activityEvent.Link.Name = "tweeted";
activityEvent.Link.Value = activityEvent.Link.Name;
}
string text = item.Summary.Text;
if (text.IndexOf(':') > 0)
text = text.Substring(text.IndexOf(':') + 2);
activityEvent.Value = text;
activityEvent.Commit();
}
}
}
return activityEvent;
}
///
/// publish a collection of activity events to the network of a userprofile
///
///
///
internal static void MulticastPublishedEvents(ActivityManager am, List activityEvents) {
if (activityEvents.Count == 0)
return;
List publishers = new List();
foreach (ActivityEvent activityEvent in activityEvents) {
if (!publishers.Contains(activityEvent.Owner.Id))
publishers.Add(activityEvent.Owner.Id);
}
Dictionary owners;
Dictionary> colleaguesOfOwners;
ActivityFeedGatherer.GetUsersColleaguesAndRights(am, publishers, out owners, out colleaguesOfOwners);
Dictionary> eventsPerOwner;
ActivityFeedGatherer.MulticastActivityEvents(am, activityEvents, colleaguesOfOwners, out eventsPerOwner);
List eventsToMulticast;
ActivityFeedGatherer.CollectActivityEventsToConsolidate(eventsPerOwner, out eventsToMulticast);
WriteEvents(am, eventsToMulticast);
}
private static void WriteEvents(ActivityManager am, List events) {
int startIndex = 0;
while (startIndex + am.MaxEventsPerBatch < events.Count) {
ActivityFeedGatherer.BatchWriteActivityEvents(events, startIndex, am.MaxEventsPerBatch);
startIndex += am.MaxEventsPerBatch;
}
ActivityFeedGatherer.BatchWriteActivityEvents(events, startIndex, events.Count - startIndex);
}
}
}