コード例 #1
0
ファイル: SyncHelpers.cs プロジェクト: JoeyVinc/CopyO2O
        /// <summary>
        /// Creates items to O365
        /// </summary>
        /// <param name="syncWork">List of sync jobs to identify the items to create</param>
        /// <param name="o365_graphcontainer">The Office365 container of the items to create (e.g. calendar or contactfolder)</param>
        /// <param name="Type">Type of the items to be processed (e.g. events or contacts)</param>
        /// <returns>Returns count of jobs run.</returns>
        ///
        public static int CreateItems(List <SyncHelpers.SyncInfo> syncWork, IEnumerable <SyncElement> srcItems, Office365.IGraphContainer o365_graphcontainer, SyncHelpers.ID_type Type)
        {
            List <Task> createTasks = new List <Task>();

            syncWork.Where(x => ((x.SyncWorkMethod == SyncHelpers.SyncMethod.CREATE) && (x.Type == Type))).ToList().ForEach(
                (item) =>
            {
                createTasks.Add(o365_graphcontainer.AddAsync(srcItems.ToList().Find(x => (x.OriginId == item.OutlookID)))
                                .ContinueWith((i) => { if (i.Result != null)
                                                       {
                                                           SyncHelpers.O365_Item_Added(i.Result, item);
                                                       }
                                              }));
            });
            Task.WaitAll(createTasks.ToArray());
            return(createTasks.Count);
        }
コード例 #2
0
ファイル: SyncHelpers.cs プロジェクト: JoeyVinc/CopyO2O
        /// <summary>
        /// Removes items from O365
        /// </summary>
        /// <param name="syncWork">List of sync job to identify the items to remove.</param>
        /// <param name="o365_graphcontainer">The Office365 container of the items to delete (e.g. calendar or contactfolder)</param>
        /// <param name="Type">Type of the items to be processed (e.g. events or contacts)</param>
        /// <returns>Returns count of jobs run.</returns>
        ///
        public static int RemoveItems(List <SyncHelpers.SyncInfo> syncWork, Office365.IGraphContainer o365_graphcontainer, SyncHelpers.ID_type Type)
        {
            List <Task> deleteTasks = new List <Task>();

            syncWork.Where(x => ((x.SyncWorkMethod == SyncHelpers.SyncMethod.DELETE) && (x.Type == Type))).ToList().ForEach(
                (item) =>
            {
                deleteTasks.Add(o365_graphcontainer.RemoveAsync(item.O365ID)
                                .ContinueWith((i) => { if (i != null)
                                                       {
                                                           SyncHelpers.O365_Item_Removed(item);
                                                       }
                                              }));
            });
            Task.WaitAll(deleteTasks.ToArray());
            return(deleteTasks.Count);
        }
コード例 #3
0
ファイル: SyncHelpers.cs プロジェクト: JoeyVinc/CopyO2O
        /// <summary>
        /// Analyse all known items and systems and prepare all required information.
        /// </summary>
        /// <param name="clrNotExisting">If TRUE all items which were identified in O365 but not exist in Outlook will be removed as well</param>
        /// <param name="syncWork">The queue for sync jobs.</param>
        /// <param name="srcItems">All items of the source system (Outlook)</param>
        /// <param name="destItems">All items of the destination system (Office 365)</param>
        /// <param name="Type">Type of the items to be processed (e.g. events or contacts)</param>
        ///
        public static void AnalyseSyncJobs(bool clrNotExisting, List <SyncHelpers.SyncInfo> syncWork, IEnumerable <SyncElement> srcItems, IEnumerable <SyncElement> destItems, SyncHelpers.ID_type Type)
        {
            //get all events which are stored in the sync cache
            List <SyncHelpers.SyncInfo> syncCache_filtered = SyncHelpers.syncCache.Where(x => x.Type == Type).ToList();

            //define NEW, MODIFIED and DELETED events of the local Outlook
            List <string> tmpNewOutlookIds      = SyncHelpers.GetIDsOfNewItems(srcItems, syncCache_filtered, OriginSystemEnum.Outlook);      //all Outlook-ids which are NOT contained in sync cache => all NEW outlook ids
            List <string> tmpModifiedOutlookIds = SyncHelpers.GetIDsOfModifiedItems(srcItems, syncCache_filtered, OriginSystemEnum.Outlook); //all Outlook-ids which were modified AFTER the last sync
            List <string> tmpDeletedOutlookIds  = SyncHelpers.GetIDsOfDeletedItems(srcItems, syncCache_filtered, OriginSystemEnum.Outlook);  //all Outlook-ids which are synced but does not exist anymore => all DELETED outlook ids

            //define NEW, MODIFIED and DELETED events of Office 365
            List <string> tmpNewO365Ids      = SyncHelpers.GetIDsOfNewItems(destItems, syncCache_filtered, OriginSystemEnum.Office365);      //all O365-ids which are NOT contained in sync cache => all NEW O365 ids
            List <string> tmpModifiedO365Ids = SyncHelpers.GetIDsOfModifiedItems(destItems, syncCache_filtered, OriginSystemEnum.Office365); //all O365-ids which were modified AFTER the last sync
            List <string> tmpDeletedO365Ids  = SyncHelpers.GetIDsOfDeletedItems(destItems, syncCache_filtered, OriginSystemEnum.Office365);  //all ids of sync cache which does NOT exist in O365 anymore => all DELETED o365 ids

            syncWork.AddRange(SyncHelpers.CollectOutlookSyncTasks(
                                  syncCache: syncCache_filtered,
                                  NewOutlookIds: tmpNewOutlookIds, ModifiedOutlookIds: tmpModifiedOutlookIds, DeletedOutlookIds: tmpDeletedOutlookIds,
                                  NewO365Ids: tmpNewO365Ids, ModifiedO365Ids: tmpModifiedO365Ids, DeletedO365Ids: tmpDeletedO365Ids,
                                  Type: Type,
                                  clrNotExisting: clrNotExisting
                                  ));
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: JoeyVinc/CopyO2O
        static void Main(string[] args)
        {
            const string  appId          = "cb2c2f84-63f0-49d8-9335-79fcc6050654";
            List <string> AppPermissions = new List <string> {
                "User.Read", "Calendars.ReadWrite", "Contacts.ReadWrite"
            };

            DateTime from = DateTime.Now.AddMonths(-1);

            from = from.AddHours(-from.Hour).AddMinutes(-from.Minute).AddSeconds(-from.Second).AddMilliseconds(-from.Millisecond);
            DateTime to = from.AddMonths(2).AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);

            int    clearpast                 = 0;
            string calendar_source_Name      = "";
            string calendar_destination_Name = "";
            string contacts_source_Name      = "";
            string contacts_destination_Name = "";
            string proxy          = "";
            bool   clrNotExisting = true;                  //clear every items of target which does not exist on source side
            bool   exitLocalOutlookAfterProcessing = true; //if the app has opened a local Outlook instance exit it at the end

            bool SyncCAL()
            {
                return((calendar_source_Name != "") && (calendar_destination_Name != ""));
            }

            bool SyncCON()
            {
                return((contacts_source_Name != "") && (contacts_destination_Name != ""));
            }

            try
            {
                //iterate through all parameters
                foreach (string arg in args)
                {
                    string parameter = arg.Trim().Split(':')[0].ToUpper();
                    string parValue  = arg.Trim().Substring(parameter.Length, arg.Trim().Length - parameter.Length).TrimStart(':');

                    switch (parameter)
                    {
                    case "/CAL":
                        if (parValue[0] == '"')
                        {
                            calendar_source_Name      = parValue.Split(';')[0].Trim('"');
                            calendar_destination_Name = parValue.Split(';')[1].Trim('"');
                            //if no dest folder was set use the default one
                            if (calendar_destination_Name == "")
                            {
                                calendar_destination_Name = null;
                            }
                        }
                        else
                        {
                            calendar_source_Name      = parValue.Split(';')[0].Trim('\'');
                            calendar_destination_Name = parValue.Split(';')[1].Trim('\'');
                            //if no dest folder was set use the default one
                            if (calendar_destination_Name == "")
                            {
                                calendar_destination_Name = null;
                            }
                        }
                        break;

                    case "/CON":
                        if (parValue[0] == '"')
                        {
                            contacts_source_Name      = parValue.Split(';')[0].Trim('"');
                            contacts_destination_Name = parValue.Split(';')[1].Trim('"');
                            //if no dest folder was set use the default one
                            if (contacts_destination_Name == "")
                            {
                                contacts_destination_Name = null;
                            }
                        }
                        else
                        {
                            contacts_source_Name      = parValue.Split(';')[0].Trim('\'');
                            contacts_destination_Name = parValue.Split(';')[1].Trim('\'');
                            //if no dest folder was set use the default one
                            if (contacts_destination_Name == "")
                            {
                                contacts_destination_Name = null;
                            }
                        }
                        break;

                    case "/FROM":
                        if (!DateTime.TryParse(parValue, out from))
                        {
                            from = DateTime.Today.AddDays(int.Parse(parValue));
                        }
                        break;

                    case "/TO":
                        if (!DateTime.TryParse(parValue, out to))
                        {
                            to = DateTime.Today.AddDays(int.Parse(parValue));
                        }
                        break;

                    case "/CLEAR":
                        clearpast = Math.Abs(int.Parse(parValue));
                        break;

                    case "/CLR":
                        clearpast = Math.Abs(int.Parse(parValue));
                        break;

                    case "/PROXY":
                        proxy = parValue;
                        break;

                    case "/DNE":
                        exitLocalOutlookAfterProcessing = false;
                        break;

                    case "/LOG":
                        logOutput = true;
                        if (parValue != "")
                        {
                            logFile = parValue;
                        }
                        break;
                    }
                }

                //check if mandatory parameters were set stop execution
                if (SyncCAL() && (calendar_source_Name.Equals("") || !calendar_source_Name.Contains("\\")))
                {
                    throw new Exception("Source calendar path not valid.");
                }

                //check if mandatory parameters were set stop execution
                if (SyncCON() && (contacts_source_Name.Equals("") || !contacts_source_Name.Contains("\\")))
                {
                    throw new Exception("Source contact folder path not valid.");
                }

                //check if from-date is lower than to-date
                if (from >= to)
                {
                    throw new Exception("FROM-date (" + from.ToShortDateString() + ") must be lower than TO-date (" + to.ToShortDateString() + ").");
                }

                //if any sync is set
                if (!SyncCAL() && !SyncCON())
                {
                    throw new Exception("At least one sync config must be set.");
                }
            }
            catch (Exception e)
            {
                LogLn("Error: " + e.Message + "\r\n", true);
                LogLn("Parameters:\r\n"
                      + "/CON:\"<source>\";\"<destination>\" : Contacts source and destination\r\n"
                      + "/CAL:\"<source>\";\"<destination>\" : Calendar source and destination\r\n"
                      + "[opt] /from:<date>              : for calendar: First date to sync (DD.MM.YYYY) or relative to today (in days; eg. -10)\r\n"
                      + "[opt] /to:<date>                : for calendar: Last date to sync (DD.MM.YYYY) or relative to today (in days; eg. 8)\r\n"
                      + "[opt] /clear:<days>             : for calendar: Clear <days> in the past (from 'from' back)\r\n"
                      + "[opt] /proxy:<address>          : set if an explicit proxy should be used for connection\r\n"
                      + "[opt] /DNE                      : if the process has started a local Outlook instance suppress the exit\r\n"
                      + "[opt] /log                      : Verbose logging\r\n\r\n"
                      + "Example: CopyO2O /CAL:\"[email protected]\\Calendar\";\"Business\" /from:-7 /to:30 /clear:14", true);
                System.Environment.Exit(-1);
            }

            LogLn("Start copy...", true);

            //load the sync cache
            SyncHelpers.LoadSyncCache();
            List <SyncHelpers.SyncInfo> syncWork = new List <SyncHelpers.SyncInfo>();

            //set proxy if set
            if (proxy != "")
            {
                System.Net.WebRequest.DefaultWebProxy = new System.Net.WebProxy(proxy, true);
            }

            Outlook.Application outlookApp = null;
            Office365.Graph     office365  = null;
            try
            {
                Log("Open Outlook...");
                outlookApp = new Outlook.Application(exitLocalOutlookAfterProcessing);
                LogLn(" Done.", false, true);

                Log("Connect to Office365...");
                office365 = new Office365.Graph(appId, AppPermissions);
                LogLn(" Done.", false, true);

                //if calendar values should be synced
                if (SyncCAL())
                {
                    LogLn("Calendar: '" + calendar_source_Name + "' >> '" + (calendar_destination_Name ?? "DEFAULT") + "'" + " from " + from.ToShortDateString() + " to " + to.ToShortDateString(), true);
                    Log("... ", true);

                    LogLn("", false, true);
                    Log("Get all events of Outlook...");
                    Outlook.Calendar src_calendar = outlookApp.GetCalendar(calendar_source_Name);
                    Events           srcEvents    = src_calendar.GetItems(from, to);
                    LogLn(" Done. " + srcEvents.Count.ToString() + " found.", false, true);

                    Log("Get all events of O365...");
                    Office365.Calendar o365_dest_calendar = office365.Calendars[calendar_destination_Name ?? "Calendar"]; //Calendar is the default calendar folder
                    Events             destEvents         = o365_dest_calendar.GetItemsAsync(from, to).Result;
                    LogLn(" Done. " + destEvents.Count.ToString() + " found.", false, true);

                    LogLn("Analyse sync tasks (NEW, MOD, DEL) ...");
                    SyncHelpers.AnalyseSyncJobs(clrNotExisting, syncWork, srcEvents, destEvents, SyncHelpers.ID_type.CalItem);
                    LogLn(" Done.");

                    LogLn("Create events in O365...");
                    int countOfcreateTasks = SyncHelpers.CreateItems(syncWork, srcEvents, o365_dest_calendar, SyncHelpers.ID_type.CalItem);
                    LogLn(" Done. (" + countOfcreateTasks + ")");

                    LogLn("Delete events in O365...");
                    int countOfdeleteTasks = SyncHelpers.RemoveItems(syncWork, o365_dest_calendar, SyncHelpers.ID_type.CalItem);
                    LogLn(" Done. (" + countOfdeleteTasks + ")");

                    //exec only if verbose logging enabled
                    if (logOutput)
                    {
                        Log("Validate count of events in O365...");
                        LogLn(" Done. " + o365_dest_calendar.GetItemsAsync(from.AddDays(-clearpast), to).Result.Count.ToString() + " found.", false, true);
                    }
                    Log("");
                    LogLn(" Done (" + srcEvents.Count.ToString() + "/" + (destEvents.Count + countOfcreateTasks - countOfdeleteTasks).ToString() + ")", true, true);
                }

                //if contacts should be synced
                if (SyncCON())
                {
                    LogLn("Contacts: '" + contacts_source_Name + "' >> '" + (contacts_destination_Name ?? "DEFAULT") + "'", true);
                    Log("... ", true);

                    LogLn("", false, true);
                    Log("Get all contacts of Outlook...");
                    Outlook.ContactFolder src_contactfolder = outlookApp.GetContactFolder(contacts_source_Name);
                    ContactCollectionType srcContacts       = src_contactfolder.GetItems();
                    LogLn(" Done. " + srcContacts.Count.ToString() + " found.", false, true);

                    Log("Get all contacts of O365...");
                    Office365.ContactFolder o365_dest_contactfolder = office365.ContactFolders[contacts_destination_Name];
                    ContactCollectionType   destContacts            = o365_dest_contactfolder.GetContactsAsync().Result;
                    LogLn(" Done. " + destContacts.Count.ToString() + " found.", false, true);

                    LogLn("Analyse sync tasks (NEW, MOD, DEL) ...");
                    SyncHelpers.AnalyseSyncJobs(clrNotExisting, syncWork, srcContacts, destContacts, SyncHelpers.ID_type.Contact);
                    LogLn(" Done.");

                    LogLn("Create contacts in O365...");
                    int countOfcreateTasks = SyncHelpers.CreateItems(syncWork, srcContacts, o365_dest_contactfolder, SyncHelpers.ID_type.Contact);
                    LogLn(" Done. (" + countOfcreateTasks + ")");

                    LogLn("Delete contacts in O365...");
                    int countOfdeleteTasks = SyncHelpers.RemoveItems(syncWork, o365_dest_contactfolder, SyncHelpers.ID_type.Contact);
                    LogLn(" Done. (" + countOfdeleteTasks + ")");

                    //exec only if verbose logging enabled
                    if (logOutput)
                    {
                        Log("Validate count of contacts in O365...");
                        LogLn(" Done. " + o365_dest_contactfolder.GetContactsAsync().Result.Count.ToString() + " found.", false, true);
                    }
                    Log("");
                    LogLn(" Done (" + srcContacts.Count.ToString() + "/" + (destContacts.Count + countOfcreateTasks - countOfdeleteTasks).ToString() + ")", true, true);
                }
            }
            catch (AggregateException ae)
            {
                ae.Handle((e) => { LogLn(" Error occured: " + e.Message, true); return(true); });
            }
            catch (System.Net.WebException e)
            {
                LogLn(" Error occured: " + e.Message + "\r\nConnection could not be establised! Proxy?", true);
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    LogLn(" Error occured: " + e.InnerException.Message, true);
                }
                else
                {
                    LogLn(" Error occured: " + e.Message, true);
                }
            }
            finally
            {
                //if outlook is still open
                if (outlookApp != null)
                {
                    Log("Close Outlook...");
                    outlookApp.Quit();
                    LogLn(" Done.", false, true);
                }

                //if a connection to office365 is still established
                if (office365 != null)
                {
                    Log("Disconnect Office365...");
                    //office365.Flush(); //finalize all open commands
                    //office365.Disconnect(); //close connection
                    office365 = null;
                    LogLn(" Done.", false, true);
                }

                //store the sync cache to disk
                SyncHelpers.StoreSyncCache();
            }

            LogLn(syncWork.Count.ToString() + " operations processed.", true);

#if DEBUG
            Console.ReadLine();
#endif
        }