public override bool ProcessUpdate(Item oldItem, Item newItem) { // base handles ItemType changing if (base.ProcessUpdate(oldItem, newItem)) { return(true); } if (newItem.Name != oldItem.Name) { // name changed, process like new item ProcessCreate(newItem); return(true); } // if the facebook ID is set or changed, retrieve FB info var fbfv = newItem.GetFieldValue(FieldNames.FacebookID); if (fbfv != null && fbfv.Value != null) { // the old category must not exist or the value must have changed var oldfbfv = oldItem.GetFieldValue(FieldNames.FacebookID); if (oldfbfv == null || oldfbfv.Value != fbfv.Value) { FBGraphAPI fbApi = new FBGraphAPI(); User userWithCreds = storage.GetUser(user.ID, true); UserCredential cred = userWithCreds.GetCredential(UserCredential.FacebookConsent); if (cred != null && cred.AccessToken != null) { fbApi.AccessToken = cred.AccessToken; } else { TraceLog.TraceError(FacebookHelper.TRACE_NO_FB_TOKEN); return(false); } // get or create an EntityRef in the UserFolder EntityRefs list var entityRefItem = storage.UserFolder.GetEntityRef(user, newItem); if (entityRefItem == null) { TraceLog.TraceError(FacebookHelper.TRACE_NO_CONTACT_ENTITYREF); return(false); } // get the contact's profile information from facebook try { // this is written as a foreach because the Query API returns an IEnumerable, but there is only one result foreach (var contact in fbApi.Query(fbfv.Value, FBQueries.BasicInformation)) { newItem.GetFieldValue(FieldNames.Picture, true).Value = String.Format("https://graph.facebook.com/{0}/picture", fbfv.Value); var birthday = (string)contact[FBQueryResult.Birthday]; if (birthday != null) { newItem.GetFieldValue(FieldNames.Birthday, true).Value = birthday; } var gender = (string)contact[FBQueryResult.Gender]; if (gender != null) { entityRefItem.GetFieldValue(FieldNames.Gender, true).Value = gender; } } //userContext.SaveChanges(); } catch (Exception ex) { TraceLog.TraceException(FacebookHelper.TRACE_NO_SAVE_FBCONTACTINFO, ex); } return(true); } } return(false); }
public bool AddCalendarEvent(Item item) { DateTime utcStartTime, utcEndTime; FieldValue fvStartTime = item.GetFieldValue(FieldNames.DueDate); FieldValue fvEndTime = item.GetFieldValue(FieldNames.EndDate); if (fvStartTime != null && !string.IsNullOrEmpty(fvStartTime.Value) && fvEndTime != null && !string.IsNullOrEmpty(fvEndTime.Value) && DateTime.TryParse(fvStartTime.Value, out utcStartTime) && DateTime.TryParse(fvEndTime.Value, out utcEndTime)) { Event calEvent = new Event() { Summary = item.Name, Start = new EventDateTime() { DateTime = XmlConvert.ToString(utcStartTime, XmlDateTimeSerializationMode.Utc) }, End = new EventDateTime() { DateTime = XmlConvert.ToString(utcEndTime, XmlDateTimeSerializationMode.Utc) }, ExtendedProperties = new Event.ExtendedPropertiesData(), }; // add item id as private extended property for event calEvent.ExtendedProperties.Private = new Event.ExtendedPropertiesData.PrivateData(); calEvent.ExtendedProperties.Private.Add(ExtensionItemID, item.ID.ToString()); FieldValue fvDescription = item.GetFieldValue(FieldNames.Description); if (fvDescription != null && !string.IsNullOrEmpty(fvDescription.Value)) { calEvent.Description = fvDescription.Value; } // TODO: investigate using Gadget to support link back to Zaplify try { EventsResource.InsertRequest eventInsertReq = this.CalendarService.Events.Insert(calEvent, UserCalendar); Event result = eventInsertReq.Fetch(); if (result.HtmlLink != null) { // add event HtmlLink as a WebLink in item FieldValue fvWebLinks = item.GetFieldValue(FieldNames.WebLinks, true); JsonWebLink webLink = new JsonWebLink() { Name = "Calendar Event", Url = result.HtmlLink }; List <JsonWebLink> webLinks = (string.IsNullOrEmpty(fvWebLinks.Value)) ? new List <JsonWebLink>() : JsonSerializer.Deserialize <List <JsonWebLink> >(fvWebLinks.Value); //var webLink = new { Name = "Calendar Event", Url = result.HtmlLink }; //var webLinks = (string.IsNullOrEmpty(fvWebLinks.Value)) ? // new List<object>() : JsonSerializer.Deserialize<List<object>>(fvWebLinks.Value); webLinks.Add(webLink); fvWebLinks.Value = JsonSerializer.Serialize(webLinks); } // add event id to UserFolder EntityRefs for item Item metaItem = storage.UserFolder.GetEntityRef(user, item); FieldValue fvCalEventID = metaItem.GetFieldValue(ExtendedFieldNames.CalEventID, true); fvCalEventID.Value = result.Id; storage.SaveChanges(); return(true); } catch (Exception e) { TraceLog.TraceException("Could not add appointment to Calendar", e); } } return(false); }
// update constants in Suggestion database to current version defined in WorkflowConstants public bool VersionConstants(string me) { try { bool updateDB = false; if (Versions.Any(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == WorkflowConstants.ConstantsVersion) == false) { // no database - create and lock the new version entry TraceLog.TraceInfo(String.Format("Suggestions database version {0} not found", WorkflowConstants.ConstantsVersion)); // remove any existing database version (there should never be more than one) foreach (var existingVersion in Versions.Where(v => v.VersionType == DatabaseVersion.Constants).ToList()) { Versions.Remove(existingVersion); } SaveChanges(); // create the new version entry DatabaseVersion ver = new DatabaseVersion() { VersionType = DatabaseVersion.Constants, VersionString = WorkflowConstants.ConstantsVersion, Status = me }; Versions.Add(ver); SaveChanges(); updateDB = true; } else { var dbVersion = Versions.Single(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == WorkflowConstants.ConstantsVersion); if (dbVersion.Status == DatabaseVersion.Corrupted) { // try to update the database again - take a lock TraceLog.TraceInfo("Suggestions database corrupted"); dbVersion.Status = me; SaveChanges(); updateDB = true; } } if (updateDB == false) { TraceLog.TraceInfo(String.Format("Suggestions database version {0} is up to date", WorkflowConstants.ConstantsVersion)); return(true); } } catch (Exception ex) { TraceLog.TraceException("Could not find database version", ex); return(false); } // update the default database values DatabaseVersion version = null; SuggestionsStorageContext versionContext = Storage.NewSuggestionsContext; try { // verify that this unit of execution owns the update lock for the database version version = versionContext.Versions.Single(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == WorkflowConstants.ConstantsVersion); if (version.Status != me) { return(true); } TraceLog.TraceInfo(String.Format("{0} updating Suggestions database to version {1}", me, WorkflowConstants.ConstantsVersion)); // remove existing intents foreach (var entity in Intents.ToList()) { Intents.Remove(entity); } var intents = WorkflowConstants.DefaultIntents(); if (intents == null) { TraceLog.TraceError("Could not find or load intents"); version.Status = DatabaseVersion.Corrupted; versionContext.SaveChanges(); return(false); } // add current intents foreach (var entity in intents) { Intents.Add(entity); } SaveChanges(); TraceLog.TraceInfo("Replaced intents"); // remove existing workflow types foreach (var entity in WorkflowTypes.ToList()) { WorkflowTypes.Remove(entity); } var workflowTypes = WorkflowConstants.DefaultWorkflowTypes(); if (workflowTypes == null) { TraceLog.TraceError("Could not find or load workflow definitions"); version.Status = DatabaseVersion.Corrupted; versionContext.SaveChanges(); return(false); } // add current workflow types foreach (var entity in workflowTypes) { WorkflowTypes.Add(entity); } SaveChanges(); TraceLog.TraceInfo("Replaced workflow types"); // save the new version number version.Status = DatabaseVersion.OK; versionContext.SaveChanges(); return(true); } catch (Exception ex) { TraceLog.TraceException("VersionConstants failed", ex); // mark the version as corrupted version.Status = DatabaseVersion.Corrupted; versionContext.SaveChanges(); return(false); } }
public override bool ProcessCreate(Item item) { // base method extracts intent if (base.ProcessCreate(item)) { return(true); } // assign category to the grocery item // create a new category fieldvalue in the item to process var categoryFV = item.GetFieldValue(FieldNames.Category, true); // check if the category for this item's name has already been saved under the $User/Grocery list // in this case, store the category in the incoming item var groceryCategoryFV = GetGroceryCategoryFieldValue(item); if (groceryCategoryFV != null && groceryCategoryFV.Value != null) { categoryFV.Value = groceryCategoryFV.Value; return(true); } // get the "intent" which in this case is the normalized name var intentName = item.Name.ToLower(); var intentFV = item.GetFieldValue(ExtendedFieldNames.Intent); if (intentFV != null && intentFV.Value != null) { intentName = intentFV.Value; } // set up the grocery API endpoint GroceryAPI gApi = new GroceryAPI(); gApi.EndpointBaseUri = string.Format("{0}{1}/", HostEnvironment.DataServicesEndpoint, "Grocery"); TraceLog.TraceDetail("GroceryAPI Endpoint: " + gApi.EndpointBaseUri); // try to find the category from the local Grocery Controller try { var results = gApi.Query(GroceryQueries.GroceryCategory, intentName).ToList(); // this should only return one result if (results.Count > 0) { // get the category foreach (var entry in results) { categoryFV.Value = entry[GroceryQueryResult.Category]; if (!String.IsNullOrEmpty(entry[GroceryQueryResult.ImageUrl])) { item.GetFieldValue(FieldNames.Picture, true).Value = entry[GroceryQueryResult.ImageUrl]; } // only grab the first category break; } TraceLog.TraceInfo(String.Format("Grocery API assigned {0} category to item {1}", categoryFV.Value, item.Name)); return(true); } } catch (Exception ex) { TraceLog.TraceException("Grocery API or database commit failed", ex); } // use the Supermarket API to get the grocery category SupermarketAPI smApi = new SupermarketAPI(); #if FALSE // use the synchronous codepath for now // execute the call asynchronously so as to not block the response smApi.BeginQuery(SupermarketQueries.SearchByProductName, item.Name, new AsyncCallback((iar) => { try { var results = smApi.EndQuery(iar); // find the item using a new context var context = Storage.NewUserContext; var groceryItem = context.Items.Single(i => i.ID == item.ID); FieldValue categoryFV = groceryItem.GetFieldValue(FieldNames.Category, true); // get the category foreach (var entry in results) { categoryFV.Value = entry[SupermarketQueryResult.Category]; // only grab the first category TraceLog.TraceInfo(String.Format("ProcessCreate: assigned {0} category to item {1}", categoryFV.Value, item.Name)); return(true); } } catch (Exception ex) { TraceLog.TraceException("ProcessCreate: Supermarket API or database commit failed", ex); } }), null); #else try { var results = smApi.Query(SupermarketQueries.SearchByProductName, intentName); // get the category and image foreach (var entry in results) { categoryFV.Value = entry[SupermarketQueryResult.Category]; if (!String.IsNullOrEmpty(entry[SupermarketQueryResult.Image])) { item.GetFieldValue(FieldNames.Picture, true).Value = entry[SupermarketQueryResult.Image]; } // write the data to the blob store BlobStore.WriteBlobData(BlobStore.GroceryContainerName, entry[SupermarketQueryResult.Name], entry.ToString()); // only grab the first category TraceLog.TraceInfo(String.Format("Supermarket API assigned {0} category to item {1}", categoryFV.Value, item.Name)); return(true); } } catch (Exception ex) { TraceLog.TraceException("Supermarket API or database commit failed", ex); } #endif return(false); }
// update constants in User database to current version defined in EntityConstants public bool VersionConstants(string me) { try { bool updateDB = false; if (Versions.Any(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == UserConstants.ConstantsVersion) == false) { // no database - create and lock the new version entry TraceLog.TraceInfo(String.Format("User database version {0} not found", UserConstants.ConstantsVersion)); // remove an existing database version (there should never be more than one) foreach (var existingVersion in Versions.Where(v => v.VersionType == DatabaseVersion.Constants).ToList()) { Versions.Remove(existingVersion); } SaveChanges(); // create the new version entry DatabaseVersion ver = new DatabaseVersion() { VersionType = DatabaseVersion.Constants, VersionString = UserConstants.ConstantsVersion, Status = me }; Versions.Add(ver); SaveChanges(); updateDB = true; } else { var dbVersion = Versions.Single(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == UserConstants.ConstantsVersion); if (dbVersion.Status == DatabaseVersion.Corrupted) { // try to update the database again - take a lock TraceLog.TraceInfo("User database corrupted"); dbVersion.Status = me; SaveChanges(); updateDB = true; } } if (updateDB == false) { TraceLog.TraceInfo(String.Format("User database version {0} is up to date", UserConstants.ConstantsVersion)); return(true); } } catch (Exception ex) { TraceLog.TraceException("Could not find database version", ex); return(false); } // update the default database values DatabaseVersion version = null; UserStorageContext versionContext = Storage.NewUserContext; try { // verify that this unit of execution owns the update lock for the database version version = versionContext.Versions.Single(v => v.VersionType == DatabaseVersion.Constants && v.VersionString == UserConstants.ConstantsVersion); if (version.Status != me) { return(true); } TraceLog.TraceInfo(String.Format("{0} updating User datatbase to version {1}", me, UserConstants.ConstantsVersion)); // update existing action types, add new action types foreach (var entity in UserConstants.DefaultActionTypes()) { if (ActionTypes.Any(e => e.ActionTypeID == entity.ActionTypeID)) { ActionTypes.Single(e => e.ActionTypeID == entity.ActionTypeID).Copy(entity); } else { ActionTypes.Add(entity); } } SaveChanges(); TraceLog.TraceInfo("Replaced action types"); // update existing colors, add new colors foreach (var entity in UserConstants.DefaultColors()) { if (Colors.Any(e => e.ColorID == entity.ColorID)) { Colors.Single(e => e.ColorID == entity.ColorID).Copy(entity); } else { Colors.Add(entity); } } SaveChanges(); TraceLog.TraceInfo("Replaced colors"); // update existing permissions, add new permissions foreach (var entity in UserConstants.DefaultPermissions()) { if (Permissions.Any(e => e.PermissionID == entity.PermissionID)) { Permissions.Single(e => e.PermissionID == entity.PermissionID).Copy(entity); } else { Permissions.Add(entity); } } SaveChanges(); TraceLog.TraceInfo("Replaced permissions"); // update existing priorities, add new priorities foreach (var entity in UserConstants.DefaultPriorities()) { if (Priorities.Any(e => e.PriorityID == entity.PriorityID)) { Priorities.Single(e => e.PriorityID == entity.PriorityID).Copy(entity); } else { Priorities.Add(entity); } } SaveChanges(); TraceLog.TraceInfo("Replaced priorities"); // update existing or add new built-in users foreach (var user in UserConstants.DefaultUsers()) { if (Users.Any(u => u.ID == user.ID)) { var existing = Users.Single(u => u.ID == user.ID); existing.Name = user.Name; existing.Email = user.Email; existing.CreateDate = user.CreateDate; } else { Users.Add(user); } } SaveChanges(); TraceLog.TraceInfo("Replaced users"); // update existing or add new built-in itemtypes and fields foreach (var itemType in UserConstants.DefaultItemTypes()) { if (ItemTypes.Any(it => it.ID == itemType.ID)) { var existing = ItemTypes.Include("Fields").Single(it => it.ID == itemType.ID); existing.Copy(itemType); if (itemType.Fields == null) { continue; } foreach (var field in itemType.Fields) { if (existing.Fields.Any(f => f.ID == field.ID)) { var existingField = existing.Fields.Single(f => f.ID == field.ID); existingField.Copy(field); } else { existing.Fields.Add(field); } } } else { ItemTypes.Add(itemType); } } SaveChanges(); TraceLog.TraceInfo("Replaced item types and fields"); // save the new version number version.Status = DatabaseVersion.OK; versionContext.SaveChanges(); return(true); } catch (Exception ex) { TraceLog.TraceException("VersionConstants failed", ex); // mark the version as corrupted version.Status = DatabaseVersion.Corrupted; versionContext.SaveChanges(); return(false); } }