private static Bucket SelectBucket(Plan plan) { if (plan.Buckets == null) { using (var httpClient = PreparePlannerClient()) { plan.Buckets = GraphResponse <BucketResponse> .Get("plans/" + plan.Id + "/buckets", httpClient).Result.Buckets; } } for (int i = 0; i < plan.Buckets.Length; i++) { Console.WriteLine("(" + i + ") " + plan.Buckets[i].Name); } string selectedBucketS = Program.GetInput("Which bucket do you want to use: "); int selectedBucket = -1; if (int.TryParse(selectedBucketS, out selectedBucket)) { return(plan.Buckets[selectedBucket]); } throw new Exception("Please select a bucket"); }
private static string GetUserForId(string id) { if (id == null) { return(null); } if (users.ContainsKey(id)) { return(users[id]); } else { using (var httpClient = PrepareUsersClient()) { try { var user = GraphResponse <UserResponse> .Get(id, httpClient).Result; users.Add(id, user.DisplayName); return(user.DisplayName); } catch { return(null); } } } }
// allows the user to search for a group, select the right one and then select the right plan // idea: if only one group matches or only one plan is in the group, that could be preselected private static Plan[] SelectPlan(bool allowMultiSelect) { using (var httpClient = PrepareGroupsClient()) { bool foundGroup = false; while (!foundGroup) { string groupSearch = Program.GetInput("Please enter the start of the name of the group containing your plan: "); var groups = GraphResponse <GroupResponse> .Get("?$filter=groupTypes/any(c:c+eq+'Unified') and startswith(displayName, '" + groupSearch + "')", httpClient).Result.Groups; if (groups.Length == 0) { Console.WriteLine("Found no matching group"); } else { foundGroup = true; Console.WriteLine("Select group:"); for (int i = 0; i < groups.Length; i++) { Console.WriteLine("(" + i + ") " + groups[i].DisplayName); } string selectedGroupS = Program.GetInput("Which group do you want to use: "); int selectedGroup = -1; if (int.TryParse(selectedGroupS, out selectedGroup)) { var plans = GraphResponse <PlanResponse> .Get(groups[selectedGroup].Id + "/planner/plans", httpClient).Result.Plans; Console.WriteLine("Select plan:"); for (int i = 0; i < plans.Length; i++) { Console.WriteLine("(" + i + ") " + plans[i].Title); } if (allowMultiSelect) { Console.WriteLine("(" + plans.Length + ") All plans"); } string selectedPlanS = Program.GetInput("Which plan do you want to use: "); int selectedPlan = -1; if (int.TryParse(selectedPlanS, out selectedPlan)) { if (selectedPlan == plans.Length) { return(plans); } else { return new Plan[] { plans[selectedPlan] } }; } } } } } throw new Exception("Please select a plan"); }
// export a plan and optionally output it as json public static Plan Export(bool output = true) { Plan plan = SelectPlan(); using (var httpClient = PreparePlannerClient()) { // get all buckets, tasks and task details var buckets = GraphResponse <BucketResponse> .Get("plans/" + plan.Id + "/buckets", httpClient).Result.Buckets; var tasks = GraphResponse <TaskResponse> .Get("plans/" + plan.Id + "/tasks", httpClient).Result.Tasks; foreach (var task in tasks) { task.TaskDetail = GraphResponse <TaskDetailResponse> .Get("tasks/" + task.Id + "/details", httpClient).Result; } // put tasks in buckets so that the plan object has all data hierarchically foreach (var bucket in buckets) { bucket.Tasks = tasks.Where(t => t.BucketId == bucket.Id).ToArray(); } plan.Buckets = buckets; } if (output) { Console.WriteLine(Serialize.ToJson(plan)); } return(plan); }
private static void CreateBucket(string targetPlanId, Bucket bucket, bool addAssignments, HttpClient httpClient) { bucket.PlanId = targetPlanId; // reset all order hints as the exported values don't work bucket.OrderHint = " !"; var newBucket = GraphResponse <Bucket> .Post("buckets", httpClient, bucket).Result; // if we are too quick the created bucket is not available yet, make sure it it there Thread.Sleep(5 * 1000); var verifyNewBucket = GraphResponse <Bucket> .Get("buckets/" + newBucket.Id, httpClient).Result; bucket.Tasks = bucket.Tasks.Reverse().ToArray(); foreach (PlannerTask task in bucket.Tasks) { task.PlanId = targetPlanId; task.BucketId = newBucket.Id; task.OrderHint = " !"; // assignments contain the users assigned to a task if (addAssignments) { foreach (Assignment assignment in task.Assignments.Values) { assignment.OrderHint = " !"; } } else { task.Assignments = new Dictionary <string, Assignment>(); } var newTask = GraphResponse <PlannerTask> .Post("tasks", httpClient, task).Result; // remember new task id for next loop task.Id = newTask.Id; } // if we are too quick the created tasks are not available yet Thread.Sleep(5 * 1000); foreach (PlannerTask task in bucket.Tasks) { var newTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Get("tasks/" + task.Id + "/details", httpClient).Result; foreach (var checklist in task.TaskDetail.Checklist.Values) { checklist.OrderHint = " !"; } foreach (var reference in task.TaskDetail.References.Values) { // same as order hint reference.PreviewPriority = " !"; } var updatedTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Patch("tasks/" + task.Id + "/details", httpClient, task.TaskDetail, newTaskDetailsResponse.OdataEtag).Result; } }
private static void CreateBucket(string targetPlanId, Bucket bucket, bool addAssignments, HttpClient httpClient) { bucket.PlanId = targetPlanId; // reset all order hints as the exported values don't work bucket.OrderHint = " !"; var newBucket = GraphResponse <Bucket> .Post("buckets", httpClient, bucket).Result; // if we are too quick the created bucket is not available yet, make sure it it there Thread.Sleep(5 * 1000); var verifyNewBucket = GraphResponse <Bucket> .Get("buckets/" + newBucket.Id, httpClient).Result; SaveTasks(targetPlanId, newBucket.Id, addAssignments, bucket.Tasks, httpClient); }
private static void SaveTasks(string targetPlanId, string bucketId, bool addAssignments, IEnumerable <PlannerTask> tasks, HttpClient httpClient) { var taskList = tasks.Reverse().ToList(); foreach (PlannerTask task in taskList) { task.PlanId = targetPlanId; task.BucketId = bucketId; task.OrderHint = " !"; // assignments contain the users assigned to a task if (addAssignments) { foreach (Assignment assignment in task.Assignments.Values) { assignment.OrderHint = " !"; } } else { task.Assignments = new Dictionary <string, Assignment>(); } var newTask = GraphResponse <PlannerTask> .Post("tasks", httpClient, task).Result; // remember new task id for next loop task.Id = newTask.Id; task.OrderHint = newTask.OrderHint; } // if we are too quick the created tasks are not available yet Thread.Sleep(5 * 1000); foreach (PlannerTask task in taskList) { var newTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Get("tasks/" + task.Id + "/details", httpClient).Result; foreach (var checklist in task.TaskDetail.Checklist.Values) { checklist.OrderHint = " !"; } foreach (var reference in task.TaskDetail.References.Values) { // same as order hint reference.PreviewPriority = " !"; } var updatedTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Patch("tasks/" + task.Id + "/details", httpClient, task.TaskDetail, newTaskDetailsResponse.OdataEtag).Result; } }
// export a plan and optionally output it as json public static Plan[] Export(bool output = true, bool allowMultiSelect = false, bool retrieveTaskDetail = true) { Plan[] plans = SelectPlan(allowMultiSelect); if (!allowMultiSelect && plans.Length > 1) { Console.WriteLine("You can only select 1 plan in this case"); return(null); } using (var httpClient = PreparePlannerClient()) { foreach (Plan plan in plans) { // get all buckets, tasks and task details var buckets = GraphResponse <BucketResponse> .Get("plans/" + plan.Id + "/buckets", httpClient).Result.Buckets; var tasks = GraphResponse <TaskResponse> .Get("plans/" + plan.Id + "/tasks", httpClient).Result.Tasks; if (retrieveTaskDetail) { foreach (var task in tasks) { task.TaskDetail = GraphResponse <TaskDetailResponse> .Get("tasks/" + task.Id + "/details", httpClient).Result; } } // put tasks in buckets so that the plan object has all data hierarchically foreach (var bucket in buckets) { bucket.Tasks = tasks.Where(t => t.BucketId == bucket.Id).ToArray(); } plan.Buckets = buckets; } } if (output) { foreach (Plan plan in plans) { Console.WriteLine(Serialize.ToJson(plan)); } } return(plans); }
// export a plan and import everything into a new plan public static void Import() { Console.WriteLine("Step 1: Select the plan to export"); Plan exportedPlan = Export(false); Console.WriteLine("Step 2: Select the plan in which you want to import"); Plan targetPlan = SelectPlan(); bool addAssignments = Program.GetInput("Do you want to import the assignments (y/n)? This might send email notifications to the assignees. ") == "y"; using (var httpClient = PreparePlannerClient()) { // buckets and tasks are always added at the beginning, therefore reversing the order when importing, otherwise e.g. the // last exported bucket would become the first bucket in the imported plan exportedPlan.Buckets = exportedPlan.Buckets.Reverse().ToArray(); // create buckets and tasks and then set details for the created tasks (can't be done in one step) foreach (Bucket bucket in exportedPlan.Buckets) { bucket.PlanId = targetPlan.Id; // reset all order hints as the exported values don't work bucket.OrderHint = " !"; var newBucket = GraphResponse <Bucket> .Post("buckets", httpClient, bucket).Result; bucket.Tasks = bucket.Tasks.Reverse().ToArray(); foreach (PlannerTask task in bucket.Tasks) { task.PlanId = targetPlan.Id; task.BucketId = newBucket.Id; task.OrderHint = " !"; // assignments contain the users assigned to a task if (addAssignments) { foreach (Assignment assignment in task.Assignments.Values) { assignment.OrderHint = " !"; } } else { task.Assignments = new Dictionary <string, Assignment>(); } var newTask = GraphResponse <PlannerTask> .Post("tasks", httpClient, task).Result; // remember new task id for next loop task.Id = newTask.Id; } // if we are too quick the created tasks are not available yet Thread.Sleep(2 * 1000); foreach (PlannerTask task in bucket.Tasks) { var newTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Get("tasks/" + task.Id + "/details", httpClient).Result; foreach (var checklist in task.TaskDetail.Checklist.Values) { checklist.OrderHint = " !"; } foreach (var reference in task.TaskDetail.References.Values) { // same as order hint reference.PreviewPriority = " !"; } var updatedTaskDetailsResponse = GraphResponse <TaskDetailResponse> .Patch("tasks/" + task.Id + "/details", httpClient, task.TaskDetail, newTaskDetailsResponse.OdataEtag).Result; } } } Console.WriteLine("Import is done"); }