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); } } }