示例#1
0
        /// <summary>
        /// Creates the file, if not exists.
        /// </summary>
        /// <param name="filePath">
        /// <see cref="CloudPact.MowblyFramework.Core.Managers.FilePath">FilePath</see> object
        /// </param>
        /// <param name="storageType">
        /// </param>
        /// <returns></returns>
        internal static string GetAbsolutePath(FilePath filePath, bool shouldCreateFile = true)
        {
            string      rootDir     = String.Empty;
            FileLevel   level       = filePath.Level;
            StorageType storageType = filePath.StorageType;
            string      path        = filePath.Path;

            if (level != FileLevel.Storage &&
                !path.StartsWith("/") &&
                !path.StartsWith("file://"))
            {
                rootDir = (storageType == StorageType.Cache) ?
                          Mowbly.CacheDirectory : Mowbly.DocumentsDirectory;
            }

            // Get the full path
            path = Path.Combine(rootDir, filePath.Path);

            // Create the file
            if (shouldCreateFile)
            {
                CreateFile(path);
            }
            return(path);
        }
示例#2
0
        /// <summary>
        /// Publishes a file based on the type of versioning required on the parent library.
        /// </summary>
        /// <param name="file">Target file to publish.</param>
        /// <param name="level">Target publish direction (Draft and Published only apply, Checkout is ignored).</param>
        public static void PublishFileToLevel(this File file, FileLevel level)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            var publishingRequired = false;
            var approvalRequired   = false;

            if (level == FileLevel.Draft || level == FileLevel.Published)
            {
                var context    = file.Context;
                var parentList = file.ListItemAllFields.ParentList;
                context.Load(parentList,
                             l => l.EnableMinorVersions,
                             l => l.EnableModeration,
                             l => l.ForceCheckout);

                var checkOutRequired = parentList.ForceCheckout;

                try
                {
                    context.ExecuteQueryRetry();
                    publishingRequired = parentList.EnableMinorVersions; // minor versions implies that the file must be published
                    approvalRequired   = parentList.EnableModeration;
                }
                catch (ServerException ex)
                {
                    if (ex.Message != "The object specified does not belong to a list.")
                    {
                        throw;
                    }
                }

                if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                {
                    LoggingUtility.Internal.TraceVerbose("Checking in file '{0}'", file.Name);
                    file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                    context.ExecuteQueryRetry();
                }

                if (level == FileLevel.Published)
                {
                    if (publishingRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Publishing file '{0}'", file.Name);
                        file.Publish("Published by provisioning");
                        context.ExecuteQueryRetry();
                    }

                    if (approvalRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Approving file '{0}'", file.Name);
                        file.Approve("Approved by provisioning");
                        context.ExecuteQueryRetry();
                    }
                }
            }
        }
        public ProjectConfigHelper(string projectId, FileLevel fileLevel = FileLevel.SOURCE)
        {
            if (String.IsNullOrEmpty(projectId))
            {
                throw new Exception(nameof(projectId));
            }

            this.ProjectId = projectId;
            this.FileLevel = fileLevel;
            InitialiseProjectConfiguration();
        }
示例#4
0
 /// <summary>
 /// Constructor for Directory class
 /// </summary>
 /// <param name="src">Source Name</param>
 /// <param name="folder">Folder Path</param>
 /// <param name="overwrite">Overwrite property</param>
 /// <param name="level">File Level</param>
 /// <param name="recursive">Recursive property</param>
 /// <param name="includeExtensions">Extensions which can be included in directory files</param>
 /// <param name="excludeExtensions">Extensions which are excluded in drectory files</param>
 /// <param name="metadataMappingFile">Metadata Mapping File</param>
 /// <param name="security">ObjectSecurity</param>
 public Directory(string src, string folder, bool overwrite,
                  FileLevel level            = FileLevel.Draft, bool recursive = false,
                  string includeExtensions   = null, string excludeExtensions  = null,
                  string metadataMappingFile = null, ObjectSecurity security   = null) :
     this()
 {
     this.Src                 = src;
     this.Folder              = folder;
     this.Overwrite           = overwrite;
     this.Level               = level;
     this.Recursive           = recursive;
     this.IncludedExtensions  = includeExtensions;
     this.ExcludedExtensions  = excludeExtensions;
     this.MetadataMappingFile = metadataMappingFile;
     if (security != null)
     {
         this.Security = security;
     }
 }
        public static File UploadFile(this Folder folder, string fileName, string localFilePath, IDictionary <string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentException("Destination file name is required.", "fileName");
            }
            if (localFilePath == null)
            {
                throw new ArgumentNullException("localFilePath");
            }
            if (string.IsNullOrWhiteSpace(localFilePath))
            {
                throw new ArgumentException("Source file path is required.", "localFilePath");
            }

            //Console.WriteLine("Provisioning file '{0}' to '{1}'", localFilePath, fileName);

            using (var localStream = new System.IO.FileStream(localFilePath, System.IO.FileMode.Open)) {
                return(UploadFile(folder, fileName, localStream, additionalProperties, replaceContent, checkHashBeforeUpload, level, useWebDav));
            }
        }
示例#6
0
 /// <summary>
 /// Constructor for the File class
 /// </summary>
 /// <param name="src">Source name of the file</param>
 /// <param name="folder">Targer Folder of the file</param>
 /// <param name="overwrite">Overwrite flag of the file</param>
 /// <param name="webParts">Webparts in the file</param>
 /// <param name="properties">Properties of the file</param>
 /// <param name="security">Security Rules of the file</param>
 /// <param name="level">Level status for the file</param>
 public File(string src, string folder, bool overwrite, IEnumerable <WebPart> webParts, IDictionary <string, string> properties, ObjectSecurity security = null, FileLevel level = FileLevel.Draft) :
     this()
 {
     this.Src       = src;
     this.Overwrite = overwrite;
     this.Level     = level;
     this.Folder    = folder;
     this.WebParts.AddRange(webParts);
     if (properties != null)
     {
         foreach (var property in properties)
         {
             this.Properties.Add(property.Key, property.Value);
         }
     }
     if (security != null)
     {
         this.Security = security;
     }
 }
        public static void PublishFileToLevel(this File file, FileLevel level)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            var publishingRequired = false;
            var approvalRequired = false;

            if (level == FileLevel.Draft || level == FileLevel.Published)
            {
                var context = file.Context;
                var parentList = file.ListItemAllFields.ParentList;
                context.Load(parentList,
                            l => l.EnableMinorVersions,
                            l => l.EnableModeration,
                            l => l.ForceCheckout);

                var checkOutRequired = false;

                try
                {
                    context.ExecuteQueryRetry();
                    checkOutRequired = parentList.ForceCheckout;
                    publishingRequired = parentList.EnableMinorVersions; // minor versions implies that the file must be published
                    approvalRequired = parentList.EnableModeration;
                }
                catch (ServerException ex)
                {
                    if (ex.Message != "The object specified does not belong to a list.")
                    {
                        throw;
                    }
                }

                if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                {
                    Log.Debug(Constants.LOGGING_SOURCE, "Checking in file '{0}'", file.Name);
                    file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                    context.ExecuteQueryRetry();
                }

                if (level == FileLevel.Published)
                {
                    if (publishingRequired)
                    {
                        Log.Debug(Constants.LOGGING_SOURCE, "Publishing file '{0}'", file.Name);
                        file.Publish("Published by provisioning");
                        context.ExecuteQueryRetry();
                    }

                    if (approvalRequired)
                    {
                        Log.Debug(Constants.LOGGING_SOURCE, "Approving file '{0}'", file.Name);
                        file.Approve("Approved by provisioning");
                        context.ExecuteQueryRetry();
                    }
                }
            }
        }
示例#8
0
        /// <summary>
        /// Uploads a file to the specified folder, but only if the contents has changed, with additional properties
        /// </summary>
        /// <param name="folder">Folder to upload file to.</param>
        /// <param name="fileName">Name of the file to upload</param>
        /// <param name="localStream">Stream containing the contents of the file</param>
        /// <param name="additionalProperties">Optional additional properties, e.g. ContentTypeId</param>
        /// <param name="replaceContent">true (default) to overwite existing files</param>
        /// <param name="checkHashBeforeUpload">true (default) to retrieve existing file and compare hash value, only uploading if the contents has changed</param>
        /// <param name="level">state to leave the file in after upload: Published (default), checked in Draft, or Checked Out</param>
        /// <param name="useWebDav">true (default) to save the binary directly (via webdav); false to use file creation</param>
        /// <returns>The uploaded File, so that additional operations (such as setting properties) can be done.</returns>
        public static File UploadFile(this Folder folder, string fileName, System.IO.Stream localStream, IDictionary<string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (fileName == null) { throw new ArgumentNullException("fileName"); }
            if (localStream == null) { throw new ArgumentNullException("localStream"); }
            if (string.IsNullOrWhiteSpace(fileName)) { throw new ArgumentException("Destination file name is required.", "fileName"); }
            // TODO: Check for any other illegal characters in SharePoint
            if (fileName.Contains('/') || fileName.Contains('\\'))
            {
                throw new ArgumentException("The argument must be a single file name and cannot contain path characters.", "fileName");
            }

            // Check for existing file
            if (!folder.IsObjectPropertyInstantiated("ServerRelativeUrl"))
            {
                folder.Context.Load(folder, f => f.ServerRelativeUrl);
                folder.Context.ExecuteQuery();
            }
            var serverRelativeUrl = folder.ServerRelativeUrl + (folder.ServerRelativeUrl.EndsWith("/") ? "" : "/") + fileName;

            bool checkOutRequired = false;
            bool publishingRequired = false;
            bool approvalRequired = false;

            // Check for existing file
            var fileCollection = folder.Files;
            File existingFile = null;
            folder.Context.Load(fileCollection);
            folder.Context.ExecuteQuery();
            foreach (var checkFile in fileCollection)
            {
                if (string.Equals(checkFile.Name, fileName, StringComparison.InvariantCultureIgnoreCase))
                {
                    existingFile = checkFile;
                    break;
                }
            }

            // Determine if upload required
            bool uploadRequired = false;
            byte[] serverHash = null;
            if (existingFile != null)
            {
                if (replaceContent)
                {
                    if (checkHashBeforeUpload)
                    {
                        var streamResult = existingFile.OpenBinaryStream();
                        folder.Context.ExecuteQuery();
                        // Hash contents
                        HashAlgorithm ha = HashAlgorithm.Create();
                        using (var serverStream = streamResult.Value)
                        {
                            serverHash = ha.ComputeHash(serverStream);
                            //Console.WriteLine("Server hash: {0}", BitConverter.ToString(serverHash));
                        }

                        // Check hash (& rewind)
                        byte[] localHash;
                        localHash = ha.ComputeHash(localStream);
                        localStream.Position = 0;
                        //Console.WriteLine("Local hash: {0}", BitConverter.ToString(localHash));

                        // Compare hash
                        var contentsMatch = true;
                        for (var index = 0; index < serverHash.Length; index++)
                        {
                            if (serverHash[index] != localHash[index])
                            {
                                //Console.WriteLine("Hash does not match");
                                contentsMatch = false;
                                break;
                            }
                        }
                        uploadRequired = !contentsMatch;
                    }
                    else
                    {
                        //Console.WriteLine("Not checking if existing file is the same; force upload");
                        uploadRequired = true;
                    }
                }
                else
                {
                    throw new Exception("File already exists, replace contents needs to be specified.");
                }
            }
            else
            {
                uploadRequired = true;
            }

            File file = null;
            // If different, upload file
            if (uploadRequired)
            {
                LoggingUtility.Internal.TraceInformation((int)EventId.UploadFile, CoreResources.FileFolderExtensions_UploadFile0ToFolder1, fileName, folder.ServerRelativeUrl);

                if (existingFile != null)
                {
                    // Existing file (upload required) -- determine if checkout required
                    var parentList = existingFile.ListItemAllFields.ParentList;
                    folder.Context.Load(parentList, l => l.ForceCheckout);
                    try
                    {
                        folder.Context.ExecuteQuery();
                        checkOutRequired = parentList.ForceCheckout;
                    }
                    catch (ServerException ex)
                    {
                        if (ex.Message != "The object specified does not belong to a list.")
                        {
                            throw;
                        }
                    }
                    //LoggingUtility.Internal.TraceVerbose("*** ForceCheckout {0}", checkOutRequired);

                    if (checkOutRequired && existingFile.CheckOutType == CheckOutType.None)
                    {
                        LoggingUtility.Internal.TraceVerbose("Checking out file '{0}'", fileName);
                        existingFile.CheckOut();
                        folder.Context.ExecuteQuery();
                    }
                }

                if (useWebDav)
                {
                    using (var uploadContext = new ClientContext(folder.Context.Url) { Credentials = folder.Context.Credentials })
                    {
                        LoggingUtility.Internal.TraceVerbose("Save binary direct (via webdav) to '{0}'", serverRelativeUrl);
                        File.SaveBinaryDirect(uploadContext, serverRelativeUrl, localStream, true);
                        uploadContext.ExecuteQuery();
                    }
                    file = folder.Files.GetByUrl(serverRelativeUrl);
                }
                else
                {
                    FileCreationInformation fileCreation = new FileCreationInformation();
                    fileCreation.ContentStream = localStream;
                    fileCreation.Url = fileName;
                    fileCreation.Overwrite = true;
                    LoggingUtility.Internal.TraceVerbose("Creating file info with Url '{0}'", fileCreation.Url);
                    file = folder.Files.Add(fileCreation);
                    folder.Context.ExecuteQuery();
                }
            }
            else
            {
                //LoggingUtility.Internal.TraceVerbose("Not uploading; existing file '{0}' in folder '{1}' is identical (hash {2})", fileName, folder.ServerRelativeUrl, BitConverter.ToString(serverHash));
                LoggingUtility.Internal.TraceVerbose("Not uploading; existing file '{0}' is identical", fileName);
                file = existingFile;
            }

            folder.Context.Load(file);
            folder.Context.ExecuteQuery();

            // Set file properties (child elements <Property>)
            var changedProperties = new Dictionary<string,string>();
            var changedPropertiesString = new StringBuilder();
            var propertyChanged = false;
            if (additionalProperties != null && additionalProperties.Count > 0)
            {
                // If this throws ServerException (does not belong to list), then shouldn't be trying to set properties)
                folder.Context.Load(file.ListItemAllFields);
                folder.Context.Load(file.ListItemAllFields.FieldValuesAsText);
                folder.Context.ExecuteQuery();

                // Loop through and detect changes first, then, check out if required and apply
                foreach (var kvp in additionalProperties)
                {
                    var propertyName = kvp.Key;
                    var propertyValue = kvp.Value;

                    var fieldValues = file.ListItemAllFields.FieldValues;
                    var currentValue = "";
                    if (file.ListItemAllFields.FieldValues.ContainsKey(propertyName))
                    {
                        currentValue = file.ListItemAllFields.FieldValuesAsText[propertyName];
                    }
                    //LoggingUtility.Internal.TraceVerbose("*** Comparing property '{0}' to current '{1}', new '{2}'", propertyName, currentValue, propertyValue);
                    switch (propertyName.ToUpperInvariant())
                    {
                        case "CONTENTTYPE":
                            {
                                // TODO: Add support for named ContentType (need to lookup ID and check if it needs changing)
                                throw new NotSupportedException("ContentType property not yet supported; use ContentTypeId instead.");
                                //break;
                            }
                        case "CONTENTTYPEID":
                            {
                                var currentBase = currentValue.Substring(0, currentValue.Length - 34);
                                var sameValue = (currentBase == propertyValue);
                                if (!sameValue && propertyValue.Length >= 32 + 6 && propertyValue.Substring(propertyValue.Length - 34, 2) == "00")
                                {
                                    var propertyBase = propertyValue.Substring(0, propertyValue.Length - 34);
                                    sameValue = (currentBase == propertyBase);
                                }
                                if (!sameValue)
                                {
                                    changedProperties[propertyName] = propertyValue;
                                    changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                                }
                                break;
                            }
                        case "PUBLISHINGASSOCIATEDCONTENTTYPE":
                            {
                                var testValue = ";#" + currentValue.Replace(", ", ";#") + ";#";
                                if (testValue != propertyValue)
                                {
                                    changedProperties[propertyName] = propertyValue;
                                    changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                                }
                                break;
                            }
                        default:
                            {
                                if (currentValue != propertyValue)
                                {
                                    //Console.WriteLine("Setting property '{0}' to '{1}'", propertyName, propertyValue);
                                    changedProperties[propertyName] = propertyValue;
                                    changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                                }
                                break;
                            }
                    }
                }

                if (changedProperties.Count > 0)
                {
                    if (!uploadRequired)
                    {
                        LoggingUtility.Internal.TraceInformation((int)EventId.UpdateFileProperties, CoreResources.FileFolderExtensions_UpdateFile0Properties1, fileName, changedPropertiesString);
                        if (existingFile != null)
                        {
                            // Existing file (no upload required, but properties were changed) -- determine if checkout required
                            var parentList = file.ListItemAllFields.ParentList;
                            folder.Context.Load(parentList, l => l.ForceCheckout);
                            try
                            {
                                folder.Context.ExecuteQuery();
                                checkOutRequired = parentList.ForceCheckout;
                            }
                            catch (ServerException ex)
                            {
                                if (ex.Message != "The object specified does not belong to a list.")
                                {
                                    throw;
                                }
                            }
                            //LoggingUtility.Internal.TraceVerbose("*** ForceCheckout2 {0}", checkOutRequired, approvalRequired);

                            if (checkOutRequired && file.CheckOutType == CheckOutType.None)
                            {
                                LoggingUtility.Internal.TraceVerbose("Checking out file '{0}'", fileName);
                                file.CheckOut();
                                folder.Context.ExecuteQuery();
                            }
                        }
                    }
                    else
                    {
                        LoggingUtility.Internal.TraceVerbose("Updating properties of file '{0}' after upload: {1}", fileName, changedPropertiesString);
                    }

                    foreach (var kvp in changedProperties)
                    {
                        var propertyName = kvp.Key;
                        var propertyValue = kvp.Value;

                        file.ListItemAllFields[propertyName] = propertyValue;
                    }
                    file.ListItemAllFields.Update();
                    folder.Context.ExecuteQuery();
                    propertyChanged = true;
                }
            }

            //LoggingUtility.Internal.TraceVerbose("*** Up {0}, Prop {1}, COT {2}, level", uploadRequired, propertyChanged, file.CheckOutType, level);

            if (uploadRequired || propertyChanged && (level == FileLevel.Draft || level == FileLevel.Published))
            {
                var parentList2 = file.ListItemAllFields.ParentList;
                folder.Context.Load(parentList2, l => l.EnableMinorVersions, l => l.EnableModeration);
                try
                {
                    folder.Context.ExecuteQuery();
                    publishingRequired = parentList2.EnableMinorVersions;
                    approvalRequired = parentList2.EnableModeration;
                }
                catch (ServerException ex)
                {
                    if (ex.Message != "The object specified does not belong to a list.")
                    {
                        throw;
                    }
                }
                //LoggingUtility.Internal.TraceVerbose("*** EnableMinorVerions {0}. EnableModeration {1}", publishingRequired, approvalRequired);

                if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                {
                    LoggingUtility.Internal.TraceVerbose("Checking in file '{0}'", fileName);
                    file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                    folder.Context.ExecuteQuery();
                }

                if (level == FileLevel.Published)
                {
                    if (publishingRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Publishing file '{0}'", fileName);
                        file.Publish("Published by provisioning");
                        folder.Context.ExecuteQuery();
                    }
                    if (approvalRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Approving file '{0}'", fileName);
                        file.Approve("Approved by provisioning");
                        folder.Context.ExecuteQuery();
                    }
                }
            }

            return file;
        }
示例#9
0
        /// <summary>
        /// Uploads a file to the specified folder, but only if the contents has changed, with additional properties
        /// </summary>
        /// <param name="folder">Folder to upload file to</param>
        /// <param name="fileName">Name of the file to upload</param>
        /// <param name="localFilePath">Location of the file to be uploaded</param>
        /// <param name="additionalProperties">Optional additional properties, e.g. ContentTypeId</param>
        /// <param name="replaceContent">true (default) to overwite existing files</param>
        /// <param name="checkHashBeforeUpload">true (default) to retrieve existing file and compare hash value, only uploading if the contents has changed</param>
        /// <param name="level">state to leave the file in after upload: Published (default), checked in Draft, or Checked Out</param>
        /// <param name="useWebDav">true (default) to save the binary directly (via webdav); false to use file creation</param>
        /// <returns>The uploaded File, so that additional operations (such as setting properties) can be done.</returns>
        public static File UploadFile(this Folder folder, string fileName, string localFilePath, IDictionary<string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (fileName == null) { throw new ArgumentNullException("fileName"); }
            if (string.IsNullOrWhiteSpace(fileName)) { throw new ArgumentException("Destination file name is required.", "fileName"); }
            if (localFilePath == null) { throw new ArgumentNullException("localFilePath"); }
            if (string.IsNullOrWhiteSpace(localFilePath)) { throw new ArgumentException("Source file path is required.", "localFilePath"); }

            //Console.WriteLine("Provisioning file '{0}' to '{1}'", localFilePath, fileName);

            using (var localStream = new System.IO.FileStream(localFilePath, System.IO.FileMode.Open))
            {
                return UploadFile(folder, fileName, localStream, additionalProperties, replaceContent, checkHashBeforeUpload, level, useWebDav);
            }
        }
示例#10
0
        /// <summary>
        /// Uploads a file to the specified folder, but only if the contents has changed, with additional properties
        /// </summary>
        /// <param name="folder">Folder to upload file to</param>
        /// <param name="localFilePath">Location of the file to be uploaded</param>
        /// <param name="additionalProperties">Optional additional properties, e.g. ContentTypeId</param>
        /// <param name="replaceContent">true (default) to overwite existing files</param>
        /// <param name="checkHashBeforeUpload">true (default) to retrieve existing file and compare hash value, only uploading if the contents has changed</param>
        /// <param name="level">state to leave the file in after upload: Published (default), checked in Draft, or Checked Out</param>
        /// <param name="useWebDav">true (default) to save the binary directly (via webdav); false to use file creation</param>
        /// <returns>The uploaded File, so that additional operations (such as setting properties) can be done.</returns>
        public static File UploadFile(this Folder folder, string localFilePath, IDictionary<string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (localFilePath == null) { throw new ArgumentNullException("localFilePath"); }
            if (string.IsNullOrWhiteSpace(localFilePath)) { throw new ArgumentException("Source file path is required.", "localFilePath"); }

            var fileName = System.IO.Path.GetFileName(localFilePath);
            using (var localStream = new System.IO.FileStream(localFilePath, System.IO.FileMode.Open))
            {
                return UploadFile(folder, fileName, localStream, additionalProperties, replaceContent, checkHashBeforeUpload, level, useWebDav);
            }
        }
示例#11
0
        /// <summary>
        /// Invoke the method specified by the
        /// <see cref="CloudPact.MowblyFramework.Core.Features.JSMessage">JSMessage</see> object
        /// </summary>
        /// <param name="message">
        /// <see cref="CloudPact.MowblyFramework.Core.Features.JSMessage">JSMessage</see> object
        /// </param>
        internal async override void InvokeAsync(JSMessage message)
        {
            string callbackId = message.CallbackId;

            try
            {
                // Variables
                SqliteConnection connection;
                DBConfig         dbConfig;
                DbTransaction    transaction;
                string           connectionId, query, queryId;
                long             dbSize;
                JObject          o;

                switch (message.Method)
                {
                case "openDatabase":

                    string    dbName     = message.Args[0] as string;
                    Int64     dblevel    = (Int64)message.Args[1];
                    FileLevel level      = (FileLevel)dblevel;
                    Int64     version    = (Int64)message.Args[2];
                    float     dbVersion  = (float)version;
                    string    dbPassword = message.Args[3] as string;
                    string    dbPath     = null;
                    if (dbName.Equals(Mowbly.GetProperty <string>(Constants.PROPERTY_LOGS_DB)))
                    {
                        dbPath = Mowbly.LogDatabaseFile;
                        if (!FileManager.FileExists(dbPath))
                        {
                            FileManager.CreateFile(dbPath);
                        }
                    }
                    else
                    {
                        dbPath = FileManager.GetAbsolutePath(new FilePath
                        {
                            Path        = Path.Combine(Constants.DIR_DB, String.Concat(dbName, dbVersion.ToString())),
                            Level       = level,
                            StorageType = StorageType.Internal
                        });
                    }

                    dbSize = FileManager.GetFileSize(dbPath);

                    // Create new connection
                    try
                    {
                        connection = new SqliteConnection();
                        connection.ConnectionString = DBUtils.GetConnectionString(dbPath, dbPassword);
                        connection.Open();
                        connectionId = Guid.NewGuid().ToString();
                        dbConfigDict.Add(connectionId, new DBConfig
                        {
                            DBName     = dbName,
                            DBVersion  = dbVersion,
                            DBPath     = dbPath,
                            DBPassword = dbPassword,
                            Connection = connection
                        });

                        InvokeCallbackJavascript(callbackId, new MethodResult {
                            Result = connectionId
                        });
                    }
                    catch (SqliteException se)
                    {
                        string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_OPEN_ERROR), se.Message);
                        Logger.Error(error);
                        JToken  opt = message.Args[0] as JToken;
                        string  Id  = opt["queryId"].ToObject <string>();
                        JObject obj = new JObject();
                        obj.Add("queryId", Id);
                        InvokeCallbackJavascript(callbackId, new MethodResult
                        {
                            Code   = MethodResult.FAILURE_CODE,
                            Result = obj,
                            Error  = new MethodError
                            {
                                Message = error
                            }
                        });
                    }

                    break;

                case "executeQuery":

                    // Get connection id
                    JToken options = message.Args[0] as JToken;
                    connectionId = options["id"].ToObject <string>();
                    dbConfig     = dbConfigDict[connectionId];

                    // Read args
                    queryId = options["queryId"].ToObject <string>();
                    query   = options["sql"].ToObject <string>().Trim();
                    List <object> queryParams = options["params"].ToObject <List <object> >();

                    // Execute query
                    try
                    {
                        JArray data         = null;
                        int    rowsAffected = 0;
                        connection = dbConfig.Connection;

                        // Throw exception is connection is null
                        if (connection == null)
                        {
                            throw new ArgumentException(Mowbly.GetString(Constants.STRING_DATABASE_NO_CONNECTION_OPEN_ERROR));
                        }

                        // Execute query
                        if (query.ToLower().StartsWith("select"))
                        {
                            data = ProcessSelectQuery(ref connection, query, queryParams);
                        }
                        else
                        {
                            rowsAffected = ProcessNonQuery(ref connection, query, queryParams);
                        }

                        // Create result
                        o = new JObject();
                        o.Add("queryId", queryId);

                        JObject d = new JObject();
                        d.Add("rowsAffected", rowsAffected);
                        d.Add("insertId", connection.LastInsertRowId);
                        d.Add("rows", data);
                        o.Add("data", d);

                        // Notify JS
                        InvokeCallbackJavascript(callbackId, new MethodResult {
                            Result = o
                        });
                    }
                    catch (SqliteException se)
                    {
                        // Error
                        string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_QUERY_ERROR), se.Message);
                        Logger.Error(error);

                        // Create result
                        o = new JObject();
                        o.Add("queryId", queryId);

                        // Notify Js
                        InvokeCallbackJavascript(callbackId, new MethodResult
                        {
                            Code   = MethodResult.FAILURE_CODE,
                            Result = o,
                            Error  = new MethodError
                            {
                                Message = error
                            }
                        });
                    }

                    break;

                case "beginTransaction":

                    connectionId = message.Args[0] as string;
                    dbConfig     = dbConfigDict[connectionId];

                    // Begin transaction
                    try
                    {
                        connection = dbConfig.Connection;
                        // Throw exception is connection is null
                        if (connection == null)
                        {
                            throw new ArgumentException(Mowbly.GetString(Constants.STRING_DATABASE_NO_CONNECTION_OPEN_ERROR));
                        }

                        transaction          = connection.BeginTransaction();
                        dbConfig.Transaction = transaction;

                        // Notify JS
                        InvokeCallbackJavascript(callbackId, new MethodResult {
                            Result = true
                        });
                    }
                    catch (SqliteException se)
                    {
                        // Error; Notify JS
                        string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_TRANSACTION_ERROR), se.Message);
                        Logger.Error(error);
                        JToken  opt = message.Args[0] as JToken;
                        string  Id  = opt["queryId"].ToObject <string>();
                        JObject obj = new JObject();
                        obj.Add("queryId", Id);
                        InvokeCallbackJavascript(callbackId, new MethodResult
                        {
                            Code   = MethodResult.FAILURE_CODE,
                            Result = obj,
                            Error  = new MethodError
                            {
                                Message = error
                            }
                        });
                    }

                    break;

                case "commit":

                    connectionId = message.Args[0] as string;
                    dbConfig     = dbConfigDict[connectionId];

                    // Commit transaction
                    try
                    {
                        transaction = dbConfig.Transaction;
                        // Throw exception is transaction is null
                        if (transaction == null)
                        {
                            throw new ArgumentException(Mowbly.GetString(Constants.STRING_DATABASE_NO_TRANSACTION_ACTIVE_ERROR));
                        }
                        transaction.Commit();

                        queryId      = message.Args[1] as string;
                        o            = new JObject();
                        o["queryId"] = queryId;
                        o["data"]    = true;

                        // Notify JS
                        InvokeCallbackJavascript(callbackId, new MethodResult {
                            Result = o
                        });
                    }
                    catch (SqliteException se)
                    {
                        // Error; Notify JS
                        string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_TRANSACTION_ERROR), se.Message);
                        Logger.Error(error);
                        JToken  opt = message.Args[0] as JToken;
                        string  Id  = opt["queryId"].ToObject <string>();
                        JObject obj = new JObject();
                        obj.Add("queryId", Id);
                        InvokeCallbackJavascript(callbackId, new MethodResult
                        {
                            Code   = MethodResult.FAILURE_CODE,
                            Result = obj,
                            Error  = new MethodError
                            {
                                Message = error
                            }
                        });
                    }

                    break;

                case "rollback":

                    connectionId = message.Args[0] as string;
                    dbConfig     = dbConfigDict[connectionId];

                    // Commit transaction
                    try
                    {
                        transaction = dbConfig.Transaction;
                        transaction.Rollback();

                        queryId      = message.Args[1] as string;
                        o            = new JObject();
                        o["queryId"] = queryId;
                        o["data"]    = true;

                        // Notify JS
                        InvokeCallbackJavascript(callbackId, new MethodResult {
                            Result = o
                        });
                    }
                    catch (SqliteException se)
                    {
                        // Error; Notify JS
                        string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_TRANSACTION_ERROR), se.Message);
                        Logger.Error(error);
                        JToken  opt = message.Args[0] as JToken;
                        string  Id  = opt["queryId"].ToObject <string>();
                        JObject obj = new JObject();
                        obj.Add("queryId", Id);
                        InvokeCallbackJavascript(callbackId, new MethodResult
                        {
                            Code   = MethodResult.FAILURE_CODE,
                            Result = obj,
                            Error  = new MethodError
                            {
                                Message = error
                            }
                        });
                    }

                    break;

                default:
                    Logger.Error("Feature " + Name + " does not support method " + message.Method);
                    break;
                }
            }
            catch (Exception e)
            {
                // Error; Notify JS
                string error = String.Concat(Mowbly.GetString(Constants.STRING_DATABASE_OPERATION_ERROR), e.Message);
                Logger.Error(error);
                JToken  opt = message.Args[0] as JToken;
                string  Id  = opt["queryId"].ToObject <string>();
                JObject obj = new JObject();
                obj.Add("queryId", Id);
                InvokeCallbackJavascript(callbackId, new MethodResult
                {
                    Code   = MethodResult.FAILURE_CODE,
                    Result = obj,
                    Error  = new MethodError
                    {
                        Message = error
                    }
                });
            }
            await Task.FromResult(0);
        }
示例#12
0
        public static File UploadFile(this Folder folder, string fileName, System.IO.Stream localStream, IDictionary <string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
            if (localStream == null)
            {
                throw new ArgumentNullException("localStream");
            }
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentException("Destination file name is required.", "fileName");
            }
            // TODO: Check for any other illegal characters in SharePoint
            if (fileName.Contains('/') || fileName.Contains('\\'))
            {
                throw new ArgumentException("The argument must be a single file name and cannot contain path characters.", "fileName");
            }

            // Check for existing file
            if (!folder.IsObjectPropertyInstantiated("ServerRelativeUrl"))
            {
                folder.Context.Load(folder, f => f.ServerRelativeUrl);
                folder.Context.ExecuteQuery();
            }
            var serverRelativeUrl = UrlUtility.Combine(folder.ServerRelativeUrl, fileName);

            bool checkOutRequired   = false;
            bool publishingRequired = false;
            bool approvalRequired   = false;

            // Check for existing file
            var  fileCollection = folder.Files;
            File existingFile   = null;

            folder.Context.Load(fileCollection);
            folder.Context.ExecuteQuery();
            foreach (var checkFile in fileCollection)
            {
                if (string.Equals(checkFile.Name, fileName, StringComparison.InvariantCultureIgnoreCase))
                {
                    existingFile = checkFile;
                    break;
                }
            }

            // Determine if upload required
            bool uploadRequired = false;

            byte[] serverHash = null;
            if (existingFile != null)
            {
                if (replaceContent)
                {
                    if (checkHashBeforeUpload)
                    {
                        var streamResult = existingFile.OpenBinaryStream();
                        folder.Context.ExecuteQuery();
                        // Hash contents
                        HashAlgorithm ha = HashAlgorithm.Create();
                        using (var serverStream = streamResult.Value) {
                            serverHash = ha.ComputeHash(serverStream);
                            //Console.WriteLine("Server hash: {0}", BitConverter.ToString(serverHash));
                        }

                        // Check hash (& rewind)
                        byte[] localHash;
                        localHash            = ha.ComputeHash(localStream);
                        localStream.Position = 0;
                        //Console.WriteLine("Local hash: {0}", BitConverter.ToString(localHash));

                        // Compare hash
                        var contentsMatch = true;
                        for (var index = 0; index < serverHash.Length; index++)
                        {
                            if (serverHash[index] != localHash[index])
                            {
                                //Console.WriteLine("Hash does not match");
                                contentsMatch = false;
                                break;
                            }
                        }
                        uploadRequired = !contentsMatch;
                    }
                    else
                    {
                        //Console.WriteLine("Not checking if existing file is the same; force upload");
                        uploadRequired = true;
                    }
                }
                else
                {
                    throw new Exception("File already exists, replace contents needs to be specified.");
                }
            }
            else
            {
                uploadRequired = true;
            }

            File file = null;

            // If different, upload file
            if (uploadRequired)
            {
                LoggingUtility.Internal.TraceInformation((int)EventId.UploadFile, CoreResources.FileFolderExtensions_UploadFile0ToFolder1, fileName, folder.ServerRelativeUrl);

                if (existingFile != null)
                {
                    // Existing file (upload required) -- determine if checkout required
                    var parentList = existingFile.ListItemAllFields.ParentList;
                    folder.Context.Load(parentList, l => l.ForceCheckout);
                    try {
                        folder.Context.ExecuteQuery();
                        checkOutRequired = parentList.ForceCheckout;
                    }
                    catch (ServerException ex) {
                        if (ex.Message != "The object specified does not belong to a list.")
                        {
                            throw;
                        }
                    }
                    //LoggingUtility.Internal.TraceVerbose("*** ForceCheckout {0}", checkOutRequired);

                    if (checkOutRequired && existingFile.CheckOutType == CheckOutType.None)
                    {
                        LoggingUtility.Internal.TraceVerbose("Checking out file '{0}'", fileName);
                        existingFile.CheckOut();
                        folder.Context.ExecuteQuery();
                    }
                }

                if (useWebDav)
                {
                    using (var uploadContext = new ClientContext(folder.Context.Url)
                    {
                        Credentials = folder.Context.Credentials
                    }) {
                        LoggingUtility.Internal.TraceVerbose("Save binary direct (via webdav) to '{0}'", serverRelativeUrl);
                        File.SaveBinaryDirect(uploadContext, serverRelativeUrl, localStream, true);
                        uploadContext.ExecuteQuery();
                    }
                    file = folder.Files.GetByUrl(serverRelativeUrl);
                }
                else
                {
                    FileCreationInformation fileCreation = new FileCreationInformation();
                    fileCreation.ContentStream = localStream;
                    fileCreation.Url           = fileName;
                    fileCreation.Overwrite     = true;
                    LoggingUtility.Internal.TraceVerbose("Creating file info with Url '{0}'", fileCreation.Url);
                    file = folder.Files.Add(fileCreation);
                    folder.Context.ExecuteQuery();
                }
            }
            else
            {
                //LoggingUtility.Internal.TraceVerbose("Not uploading; existing file '{0}' in folder '{1}' is identical (hash {2})", fileName, folder.ServerRelativeUrl, BitConverter.ToString(serverHash));
                LoggingUtility.Internal.TraceVerbose("Not uploading; existing file '{0}' is identical", fileName);
                file = existingFile;
            }

            folder.Context.Load(file);
            folder.Context.ExecuteQuery();

            // Set file properties (child elements <Property>)
            var changedProperties       = new Dictionary <string, string>();
            var changedPropertiesString = new StringBuilder();
            var propertyChanged         = false;

            if (additionalProperties != null && additionalProperties.Count > 0)
            {
                // If this throws ServerException (does not belong to list), then shouldn't be trying to set properties)
                folder.Context.Load(file.ListItemAllFields);
                folder.Context.Load(file.ListItemAllFields.FieldValuesAsText);
                folder.Context.ExecuteQuery();

                // Loop through and detect changes first, then, check out if required and apply
                foreach (var kvp in additionalProperties)
                {
                    var propertyName  = kvp.Key;
                    var propertyValue = kvp.Value;

                    var fieldValues  = file.ListItemAllFields.FieldValues;
                    var currentValue = "";
                    if (file.ListItemAllFields.FieldValues.ContainsKey(propertyName))
                    {
                        currentValue = file.ListItemAllFields.FieldValuesAsText[propertyName];
                    }
                    //LoggingUtility.Internal.TraceVerbose("*** Comparing property '{0}' to current '{1}', new '{2}'", propertyName, currentValue, propertyValue);
                    switch (propertyName.ToUpperInvariant())
                    {
                    case "CONTENTTYPE": {
                        // TODO: Add support for named ContentType (need to lookup ID and check if it needs changing)
                        throw new NotSupportedException("ContentType property not yet supported; use ContentTypeId instead.");
                        //break;
                    }

                    case "CONTENTTYPEID": {
                        var currentBase = currentValue.Substring(0, currentValue.Length - 34);
                        var sameValue   = (currentBase == propertyValue);
                        if (!sameValue && propertyValue.Length >= 32 + 6 && propertyValue.Substring(propertyValue.Length - 34, 2) == "00")
                        {
                            var propertyBase = propertyValue.Substring(0, propertyValue.Length - 34);
                            sameValue = (currentBase == propertyBase);
                        }
                        if (!sameValue)
                        {
                            changedProperties[propertyName] = propertyValue;
                            changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                        }
                        break;
                    }

                    case "PUBLISHINGASSOCIATEDCONTENTTYPE": {
                        var testValue = ";#" + currentValue.Replace(", ", ";#") + ";#";
                        if (testValue != propertyValue)
                        {
                            changedProperties[propertyName] = propertyValue;
                            changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                        }
                        break;
                    }

                    default: {
                        if (currentValue != propertyValue)
                        {
                            //Console.WriteLine("Setting property '{0}' to '{1}'", propertyName, propertyValue);
                            changedProperties[propertyName] = propertyValue;
                            changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue);
                        }
                        break;
                    }
                    }
                }

                if (changedProperties.Count > 0)
                {
                    if (!uploadRequired)
                    {
                        LoggingUtility.Internal.TraceInformation((int)EventId.UpdateFileProperties, CoreResources.FileFolderExtensions_UpdateFile0Properties1, fileName, changedPropertiesString);
                        if (existingFile != null)
                        {
                            // Existing file (no upload required, but properties were changed) -- determine if checkout required
                            var parentList = file.ListItemAllFields.ParentList;
                            folder.Context.Load(parentList, l => l.ForceCheckout);
                            try {
                                folder.Context.ExecuteQuery();
                                checkOutRequired = parentList.ForceCheckout;
                            }
                            catch (ServerException ex) {
                                if (ex.Message != "The object specified does not belong to a list.")
                                {
                                    throw;
                                }
                            }
                            //LoggingUtility.Internal.TraceVerbose("*** ForceCheckout2 {0}", checkOutRequired, approvalRequired);

                            if (checkOutRequired && file.CheckOutType == CheckOutType.None)
                            {
                                LoggingUtility.Internal.TraceVerbose("Checking out file '{0}'", fileName);
                                file.CheckOut();
                                folder.Context.ExecuteQuery();
                            }
                        }
                    }
                    else
                    {
                        LoggingUtility.Internal.TraceVerbose("Updating properties of file '{0}' after upload: {1}", fileName, changedPropertiesString);
                    }

                    foreach (var kvp in changedProperties)
                    {
                        var propertyName  = kvp.Key;
                        var propertyValue = kvp.Value;

                        file.ListItemAllFields[propertyName] = propertyValue;
                    }
                    file.ListItemAllFields.Update();
                    folder.Context.ExecuteQuery();
                    propertyChanged = true;
                }
            }

            //LoggingUtility.Internal.TraceVerbose("*** Up {0}, Prop {1}, COT {2}, level", uploadRequired, propertyChanged, file.CheckOutType, level);

            if (uploadRequired || propertyChanged && (level == FileLevel.Draft || level == FileLevel.Published))
            {
                var parentList2 = file.ListItemAllFields.ParentList;
                folder.Context.Load(parentList2, l => l.EnableMinorVersions, l => l.EnableModeration);
                try {
                    folder.Context.ExecuteQuery();
                    publishingRequired = parentList2.EnableMinorVersions;
                    approvalRequired   = parentList2.EnableModeration;
                }
                catch (ServerException ex) {
                    if (ex.Message != "The object specified does not belong to a list.")
                    {
                        throw;
                    }
                }
                //LoggingUtility.Internal.TraceVerbose("*** EnableMinorVerions {0}. EnableModeration {1}", publishingRequired, approvalRequired);

                if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                {
                    LoggingUtility.Internal.TraceVerbose("Checking in file '{0}'", fileName);
                    file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                    folder.Context.ExecuteQuery();
                }

                if (level == FileLevel.Published)
                {
                    if (publishingRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Publishing file '{0}'", fileName);
                        file.Publish("Published by provisioning");
                        folder.Context.ExecuteQuery();
                    }
                    if (approvalRequired)
                    {
                        LoggingUtility.Internal.TraceVerbose("Approving file '{0}'", fileName);
                        file.Approve("Approved by provisioning");
                        folder.Context.ExecuteQuery();
                    }
                }
            }

            return(file);
        }
示例#13
0
 /// <summary>
 /// Uploads all files in the specified local folder, after checking a hash value for changes, to the destination folder.
 /// </summary>
 /// <param name="sourcePath">Local folder to upload</param>
 /// <param name="destinationPrefixedUrl">Server relative URL of the destination folder; may use '~sitecollection/' or '~site/' prefix; the folder must already exist</param>
 /// <param name="publishingLevel">Target final state of the file, e.g. Published or Draft</param>
 public SynchronizationResult SynchronizeFolder(string sourcePath, string destinationPrefixedUrl, FileLevel publishingLevel)
 {
     using (_configuration.ContextManager.ContextScope(_configuration.Log))
     {
         return(SynchronizeFolderInternal(sourcePath, _configuration.ContextManager.CurrentContext.Web, destinationPrefixedUrl, publishingLevel));
     }
 }
        public static void PublishFileToLevel(this File file, FileLevel level)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            var publishingRequired = false;
            var approvalRequired = false;

            if (level == FileLevel.Draft || level == FileLevel.Published)
            {
                var context = file.Context;

                bool normalFile = true;
                var checkOutRequired = false;
                if (normalFile)
                {
                    var parentList = file.ListItemAllFields.ParentList;
                    context.Load(parentList,
                                l => l.EnableMinorVersions,
                                l => l.EnableModeration,
                                l => l.ForceCheckout);

                    try
                    {
                        context.ExecuteQueryRetry();
                        checkOutRequired = parentList.ForceCheckout;
                        publishingRequired = parentList.EnableMinorVersions; // minor versions implies that the file must be published
                        approvalRequired = parentList.EnableModeration;
                    }
                    catch (ServerException ex)
                    {
                        if (ex.Message != "The object specified does not belong to a list.")
                        {
                            if (ex.Message.StartsWith("Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null.") &&
                                ex.Message.Contains("ListItemAllFields"))
                            {
                                // E.g. custom display form aspx page being uploaded to the libraries Forms folder
                                normalFile = false;
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                }

                if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                {
                    Log.Debug(Constants.LOGGING_SOURCE, "Checking in file '{0}'", file.Name);
                    file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                    context.ExecuteQueryRetry();
                }

                if (level == FileLevel.Published)
                {
                    if (publishingRequired)
                    {
                        Log.Debug(Constants.LOGGING_SOURCE, "Publishing file '{0}'", file.Name);
                        file.Publish("Published by provisioning");
                        context.ExecuteQueryRetry();
                    }

                    if (approvalRequired)
                    {
                        Log.Debug(Constants.LOGGING_SOURCE, "Approving file '{0}'", file.Name);
                        file.Approve("Approved by provisioning");
                        context.ExecuteQueryRetry();
                    }
                }
            }
        }
        public static File UploadFile(this Folder folder, string localFilePath, IDictionary <string, string> additionalProperties = null, bool replaceContent = true, bool checkHashBeforeUpload = true, FileLevel level = FileLevel.Published, bool useWebDav = true)
        {
            if (localFilePath == null)
            {
                throw new ArgumentNullException("localFilePath");
            }
            if (string.IsNullOrWhiteSpace(localFilePath))
            {
                throw new ArgumentException("Source file path is required.", "localFilePath");
            }

            var fileName = Path.GetFileName(localFilePath);

            using (var localStream = new FileStream(localFilePath, FileMode.Open)) {
                return(UploadFile(folder, fileName, localStream, additionalProperties, replaceContent, checkHashBeforeUpload, level, useWebDav));
            }
        }
示例#16
0
        private Tuple <File, UploadInfo> UploadFileInternal(System.IO.Stream stream, Web web, Folder destinationFolder, string sourceFilePath, string destinationFileServerRelativeUrl, FileLevel publishingLevel)
        {
            File file = null;

            byte[] localHash = null;
            bool   changed   = false;

            var splitIndex = destinationFileServerRelativeUrl.LastIndexOf('/');
            var fileName   = destinationFileServerRelativeUrl.Substring(splitIndex + 1);

            byte[] serverHash    = _configuration.HashProvider.GetFileHash(_configuration.ContextManager, _configuration.Log, destinationFileServerRelativeUrl);
            bool   contentsMatch = false;

            //            _configuration.Log.Information("DEBUG: Check hash: {0}", BitConverter.ToString(serverHash));

            using (var streamPreprocessor = new StreamPreprocessor(_configuration.ContextManager, _configuration.Log, stream, _configuration.Preprocessors))
            {
                // Compare hash
                HashAlgorithm ha = HashAlgorithm.Create();
                localHash = ha.ComputeHash(streamPreprocessor.Stream);
                streamPreprocessor.Stream.Position = 0;
                //                _configuration.Log.Information("DEBUG: Local hash: {0}", BitConverter.ToString(localHash));
                if (localHash.Length == serverHash.Length)
                {
                    contentsMatch = true;
                    for (var index = 0; index < serverHash.Length; index++)
                    {
                        if (serverHash[index] != localHash[index])
                        {
                            //Console.WriteLine("Hash does not match");
                            contentsMatch = false;
                            break;
                        }
                    }
                }

                if (!contentsMatch)
                {
                    // Checkout if required
                    var checkOutRequired = false;
                    file = web.GetFileByServerRelativeUrl(destinationFileServerRelativeUrl);
                    _configuration.ContextManager.CurrentContext.Load(file, f => f.CheckOutType);
                    try
                    {
                        _configuration.ContextManager.CurrentContext.ExecuteQuery();

                        var parentList = file.ListItemAllFields.ParentList;
                        _configuration.ContextManager.CurrentContext.Load(parentList, l => l.ForceCheckout);
                        try
                        {
                            _configuration.ContextManager.CurrentContext.ExecuteQuery();
                            if (parentList.ForceCheckout && file.CheckOutType == CheckOutType.None)
                            {
                                checkOutRequired = true;
                            }
                        }
                        catch (ServerException ex)
                        {
                            if (ex.Message != "The object specified does not belong to a list.")
                            {
                                throw;
                            }
                        }
                    }
                    catch (ServerException ex)
                    {
                        if (ex.Message != "File Not Found.")
                        {
                            throw;
                        }
                    }
                    if (checkOutRequired)
                    {
                        _configuration.Log.Information("Checking out file '{0}'", destinationFileServerRelativeUrl);
                        file.CheckOut();
                        _configuration.ContextManager.CurrentContext.ExecuteQuery();
                    }

                    // Upload file
                    var newFileInfo = new FileCreationInformation()
                    {
                        ContentStream = streamPreprocessor.Stream,
                        Url           = fileName,
                        Overwrite     = true
                    };
                    _configuration.Log.Information("{0} : updating ({1}..)", destinationFileServerRelativeUrl, BitConverter.ToString(localHash).Substring(0, 12));
                    file = destinationFolder.Files.Add(newFileInfo);
                    _configuration.ContextManager.CurrentContext.Load(file);
                    _configuration.ContextManager.CurrentContext.ExecuteQuery();
                    changed = true;

                    // Check in and publish
                    var publishingRequired = false;
                    var approvalRequired   = false;
                    if (publishingLevel == FileLevel.Draft || publishingLevel == FileLevel.Published)
                    {
                        var context    = file.Context;
                        var parentList = file.ListItemAllFields.ParentList;
                        context.Load(parentList,
                                     l => l.EnableMinorVersions,
                                     l => l.EnableModeration,
                                     l => l.ForceCheckout);
                        try
                        {
                            context.ExecuteQuery();
                            checkOutRequired   = parentList.ForceCheckout;
                            publishingRequired = parentList.EnableMinorVersions; // minor versions implies that the file must be published
                            approvalRequired   = parentList.EnableModeration;
                        }
                        catch (ServerException ex)
                        {
                            if (ex.Message != "The object specified does not belong to a list.")
                            {
                                throw;
                            }
                        }
                        if (file.CheckOutType != CheckOutType.None || checkOutRequired)
                        {
                            _configuration.Log.Information("Checking in file '{0}'", file.Name);
                            file.CheckIn("Checked in by provisioning", publishingRequired ? CheckinType.MinorCheckIn : CheckinType.MajorCheckIn);
                            context.ExecuteQuery();
                        }
                        if (publishingLevel == FileLevel.Published)
                        {
                            if (publishingRequired)
                            {
                                _configuration.Log.Information("Publishing file '{0}'", file.Name);
                                file.Publish("Published by provisioning");
                                context.ExecuteQuery();
                            }

                            if (approvalRequired)
                            {
                                _configuration.Log.Information("Approving file '{0}'", file.Name);
                                file.Approve("Approved by provisioning");
                                context.ExecuteQuery();
                            }
                        }
                    }

                    _configuration.HashProvider.StoreFileHash(_configuration.ContextManager, _configuration.Log, destinationFileServerRelativeUrl, localHash);
                }
                else
                {
                    _configuration.Log.Information("{0} : no change ({1}..).", destinationFileServerRelativeUrl, BitConverter.ToString(serverHash).Substring(0, 12));
                }
            }

            var syncInfo = new UploadInfo(sourceFilePath, destinationFileServerRelativeUrl, changed, localHash);

            return(Tuple.Create(file, syncInfo));
        }
示例#17
0
        private SynchronizationResult SynchronizeFolderInternal(string sourcePath, Web web, string destinationPrefixedUrl, FileLevel publishingLevel)
        {
            // TODO: Consider adding recursive, but think about subfolder creation.

            if (sourcePath == null)
            {
                throw new ArgumentNullException("sourcePath");
            }
            if (web == null)
            {
                throw new ArgumentNullException("web");
            }
            if (destinationPrefixedUrl == null)
            {
                throw new ArgumentNullException("destinationPrefixedUrl");
            }

            var processedFiles = new List <UploadInfo>();

            try
            {
                //if (recursive)
                //{
                //    throw new NotSupportedException("Recursive not supported yet");
                //}

                var assembly = Assembly.GetExecutingAssembly();
                var fvi      = FileVersionInfo.GetVersionInfo(assembly.Location);
                _configuration.Log.Information("IonFar SharePoint Synchronizer v" + fvi.FileVersion);

                _configuration.Log.Information("== Uploading folder '{0}' ==", destinationPrefixedUrl);

                var destinationServerRelativeUrl = SPUrlUtility.ResolveServerRelativeUrl(_configuration.ContextManager.CurrentContext.Site, web, destinationPrefixedUrl);
                var destinationFolder            = web.GetFolderByServerRelativeUrl(destinationServerRelativeUrl);

                var filePaths = System.IO.Directory.EnumerateFiles(sourcePath);
                foreach (var filePath in filePaths)
                {
                    var fileName = System.IO.Path.GetFileName(filePath);
                    var fileUrl  = SPUrlUtility.Combine(destinationServerRelativeUrl, fileName);

                    using (var localStream = System.IO.File.OpenRead(filePath))
                    {
                        var uploadResult = UploadFileInternal(localStream, web, destinationFolder, filePath, fileUrl, publishingLevel);
                        processedFiles.Add(uploadResult.Item2);
                    }
                }

                return(new SynchronizationResult(processedFiles, successful: true, error: null));
            }
            catch (Exception ex)
            {
                _configuration.Log.Error(
                    "Synchronization failed and the environment has been left in a partially complete state, manual intervention may be required.\nException: {0}", ex
                    );
                return(new SynchronizationResult(processedFiles, successful: false, error: ex));
            }
        }
示例#18
0
        /// <summary>
        /// Uploads a file, replacing any existing file with a new version.
        /// </summary>
        /// <param name="stream">Contents of the file to upload</param>
        /// <param name="web">Web the destination folder exists in</param>
        /// <param name="destinationPrefixedUrl">Server relative URL of the destination file; may use '~sitecollection/' or '~site/' prefix; the folder must already exist</param>
        /// <param name="publishingLevel">Target final state of the file, e.g. Published or Draft</param>
        /// <returns>The updated or newly created file</returns>
        public File UploadFile(System.IO.Stream stream, Web web, string destinationPrefixedUrl, FileLevel publishingLevel)
        {
            var destinationFileServerRelativeUrl   = SPUrlUtility.ResolveServerRelativeUrl(_configuration.ContextManager.CurrentContext.Site, web, destinationPrefixedUrl);
            var destinationFolderServerRelativeUrl = destinationFileServerRelativeUrl.Substring(0, destinationFileServerRelativeUrl.LastIndexOf('/'));
            //            _configuration.Log.Information("DEBUG: file '{0}', folder '{1}'", fileName, folderServerRelativeUrl);
            var destinationFolder = web.GetFolderByServerRelativeUrl(destinationFolderServerRelativeUrl);

            var result = UploadFileInternal(stream, web, destinationFolder, null, destinationFileServerRelativeUrl, publishingLevel);

            return(result.Item1);
        }