示例#1
0
        /// <summary>
        /// Maps the specified folder.
        /// </summary>
        /// <param name="folder">The folder.</param>
        /// <param name="ministryFileType">Type of the ministry file.</param>
        /// <param name="storageProvider">The storage provider.</param>
        public void Map(ZipArchive folder, BinaryFileType ministryFileType, ProviderComponent storageProvider)
        {
            var lookupContext      = new RockContext();
            var personEntityTypeId = EntityTypeCache.GetId <Person>();
            var fileFieldTypeId    = FieldTypeCache.Read(Rock.SystemGuid.FieldType.FILE.AsGuid(), lookupContext).Id;

            var existingAttributes = new AttributeService(lookupContext).GetByFieldTypeId(fileFieldTypeId)
                                     .Where(a => a.EntityTypeId == personEntityTypeId)
                                     .ToDictionary(a => a.Key, a => a.Id);

            var emptyJsonObject = "{}";
            var newFileList     = new List <DocumentKeys>();

            int completed  = 0;
            int totalRows  = folder.Entries.Count;
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying files import ({0:N0} found.", totalRows));

            foreach (var file in folder.Entries)
            {
                var fileExtension = Path.GetExtension(file.Name);
                var fileMimeType  = Extensions.GetMIMEType(file.Name);
                if (BinaryFileComponent.FileTypeBlackList.Contains(fileExtension))
                {
                    LogException("Binary File Import", string.Format("{0} filetype not allowed ({1})", fileExtension, file.Name));
                    continue;
                }
                else if (fileMimeType == null)
                {
                    LogException("Binary File Import", string.Format("{0} filetype not recognized ({1})", fileExtension, file.Name));
                    continue;
                }

                string[] parsedFileName = file.Name.Split('_');
                // Ministry docs should follow this pattern:
                // 0. Firstname
                // 1. Lastname
                // 2. ForeignId
                // 3. Filename

                var personForeignId = parsedFileName[2].AsType <int?>();
                var personKeys      = BinaryFileComponent.ImportedPeople.FirstOrDefault(p => p.IndividualId == personForeignId);
                if (personKeys != null)
                {
                    var rockFile = new Rock.Model.BinaryFile();
                    rockFile.IsSystem         = false;
                    rockFile.IsTemporary      = false;
                    rockFile.FileName         = file.Name;
                    rockFile.MimeType         = fileMimeType;
                    rockFile.BinaryFileTypeId = ministryFileType.Id;
                    rockFile.CreatedDateTime  = file.LastWriteTime.DateTime;
                    rockFile.ModifiedDateTime = ImportDateTime;
                    rockFile.Description      = string.Format("Imported as {0}", file.Name);
                    rockFile.SetStorageEntityTypeId(ministryFileType.StorageEntityTypeId);
                    rockFile.StorageEntitySettings = emptyJsonObject;

                    if (ministryFileType.AttributeValues.Any())
                    {
                        rockFile.StorageEntitySettings = ministryFileType.AttributeValues
                                                         .ToDictionary(a => a.Key, v => v.Value.Value).ToJson();
                    }

                    // use base stream instead of file stream to keep the byte[]
                    // NOTE: if byte[] converts to a string it will corrupt the stream
                    using (var fileContent = new StreamReader(file.Open()))
                    {
                        rockFile.ContentStream = new MemoryStream(fileContent.BaseStream.ReadBytesToEnd());
                    }

                    var attributePattern = "[A-Za-z0-9-]+";
                    var attributeName    = Regex.Match(parsedFileName[3].RemoveWhitespace(), attributePattern);
                    var attributeKey     = attributeName.Value.RemoveWhitespace();

                    // change key to default key for Background Check Documents
                    if (attributeKey == "BackgroundCheck")
                    {
                        attributeKey = "BackgroundCheckDocument";
                    }

                    if (!existingAttributes.ContainsKey(attributeKey))
                    {
                        var newAttribute = new Attribute();
                        newAttribute.FieldTypeId  = fileFieldTypeId;
                        newAttribute.EntityTypeId = personEntityTypeId;
                        newAttribute.EntityTypeQualifierColumn = string.Empty;
                        newAttribute.EntityTypeQualifierValue  = string.Empty;
                        newAttribute.Key              = attributeKey;
                        newAttribute.Name             = attributeName.Value;
                        newAttribute.Description      = attributeName.Value + " created by binary file import";
                        newAttribute.CreatedDateTime  = ImportDateTime;
                        newAttribute.ModifiedDateTime = ImportDateTime;
                        newAttribute.IsGridColumn     = false;
                        newAttribute.IsMultiValue     = false;
                        newAttribute.IsRequired       = false;
                        newAttribute.AllowSearch      = false;
                        newAttribute.IsSystem         = false;
                        newAttribute.Order            = 0;

                        newAttribute.AttributeQualifiers.Add(new AttributeQualifier()
                        {
                            Key   = "binaryFileType",
                            Value = ministryFileType.Guid.ToString()
                        });

                        lookupContext.Attributes.Add(newAttribute);
                        lookupContext.SaveChanges();

                        existingAttributes.Add(newAttribute.Key, newAttribute.Id);
                    }

                    newFileList.Add(new DocumentKeys()
                    {
                        PersonId    = personKeys.PersonId,
                        AttributeId = existingAttributes[attributeKey],
                        File        = rockFile
                    });

                    completed++;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} files imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFiles(newFileList, storageProvider);

                        // Reset list
                        newFileList.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newFileList.Any())
            {
                SaveFiles(newFileList, storageProvider);
            }

            ReportProgress(100, string.Format("Finished files import: {0:N0} addresses imported.", completed));
        }
示例#2
0
        /// <summary>
        /// Maps the specified folder.
        /// </summary>
        /// <param name="folder">The folder.</param>
        /// <param name="ministryFileType">Type of the ministry file.</param>
        public int Map(ZipArchive folder, BinaryFileType ministryFileType)
        {
            var lookupContext         = new RockContext();
            var personEntityTypeId    = EntityTypeCache.GetId <Person>();
            var binaryFileTypeService = new BinaryFileTypeService(lookupContext);
            var fileFieldTypeId       = FieldTypeCache.Get(Rock.SystemGuid.FieldType.FILE.AsGuid(), lookupContext).Id;
            var backgroundFieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.BACKGROUNDCHECK.AsGuid(), lookupContext).Id;

            var existingAttributes = new AttributeService(lookupContext).GetByFieldTypeId(fileFieldTypeId)
                                     .Where(a => a.EntityTypeId == personEntityTypeId)
                                     .ToDictionary(a => a.Key, a => a);

            var backgroundCheckFileAttributes = new AttributeService(lookupContext).GetByFieldTypeId(backgroundFieldTypeId)
                                                .Where(a => a.EntityTypeId == personEntityTypeId)
                                                .ToDictionary(a => a.Key, a => a);

            foreach (var backgroundCheckFileAttribute in backgroundCheckFileAttributes)
            {
                if (!existingAttributes.ContainsKey(backgroundCheckFileAttribute.Key))
                {
                    existingAttributes.Add(backgroundCheckFileAttribute.Key, backgroundCheckFileAttribute.Value);
                }
            }

            var emptyJsonObject = "{}";
            var newFileList     = new List <DocumentKeys>();

            var completedItems = 0;
            var totalRows      = folder.Entries.Count;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying ministry document import ({0:N0} found)", totalRows));

            foreach (var file in folder.Entries.OrderBy(f => f.Name))
            {
                var fileExtension = Path.GetExtension(file.Name);
                if (FileTypeBlackList.Contains(fileExtension))
                {
                    LogException("Binary File Import", string.Format("{0} filetype not allowed ({1})", fileExtension, file.Name));
                    continue;
                }

                var nameWithoutExtension = file.Name.ReplaceLastOccurrence(fileExtension, string.Empty);
                var parsedFileName       = nameWithoutExtension.Split('_');
                // Ministry docs should follow this pattern:
                // 0. Firstname
                // 1. Lastname
                // 2. ForeignId
                // 3. Filename
                // 4. Doc Id
                if (parsedFileName.Length < 3)
                {
                    break;
                }

                var personForeignId = parsedFileName[2].AsType <int?>();
                var personKeys      = ImportedPeople.FirstOrDefault(p => p.PersonForeignId == personForeignId);
                if (personKeys != null)
                {
                    var attributeName     = string.Empty;
                    var documentForeignId = string.Empty;
                    if (parsedFileName.Count() > 4)
                    {
                        attributeName     = parsedFileName[3];
                        documentForeignId = parsedFileName[4];
                    }
                    else
                    {
                        var filename = parsedFileName[3].ReplaceLastOccurrence(fileExtension, string.Empty);
                        attributeName     = Regex.Replace(filename, "\\d{4,}[.\\w]+$", string.Empty);
                        documentForeignId = Regex.Match(filename, "\\d+$").Value;
                    }

                    // append "Document" to attribute name to create unique attributes
                    // this matches core attribute "Background Check Document"
                    attributeName = !attributeName.EndsWith("Document", StringComparison.OrdinalIgnoreCase) ? string.Format("{0} Document", attributeName) : attributeName;
                    var attributeKey = attributeName.RemoveSpecialCharacters();

                    Attribute fileAttribute           = null;
                    var       attributeBinaryFileType = ministryFileType;
                    if (!existingAttributes.ContainsKey(attributeKey))
                    {
                        fileAttribute = new Attribute
                        {
                            FieldTypeId  = fileFieldTypeId,
                            EntityTypeId = personEntityTypeId,
                            EntityTypeQualifierColumn = string.Empty,
                            EntityTypeQualifierValue  = string.Empty,
                            Key          = attributeKey,
                            Name         = attributeName,
                            Description  = string.Format("{0} created by binary file import", attributeName),
                            IsGridColumn = false,
                            IsMultiValue = false,
                            IsRequired   = false,
                            AllowSearch  = false,
                            IsSystem     = false,
                            Order        = 0
                        };

                        fileAttribute.AttributeQualifiers.Add(new AttributeQualifier()
                        {
                            Key   = "binaryFileType",
                            Value = ministryFileType.Guid.ToString()
                        });

                        lookupContext.Attributes.Add(fileAttribute);
                        lookupContext.SaveChanges();

                        existingAttributes.Add(fileAttribute.Key, fileAttribute);
                    }
                    else
                    {
                        // if attribute already exists in Rock, override default file type with the Rock-specified file type
                        fileAttribute = existingAttributes[attributeKey];
                        var attributeBinaryFileTypeGuid = fileAttribute.AttributeQualifiers.FirstOrDefault(q => q.Key.Equals("binaryFileType"));
                        if (attributeBinaryFileTypeGuid != null)
                        {
                            attributeBinaryFileType = binaryFileTypeService.Get(attributeBinaryFileTypeGuid.Value.AsGuid());
                        }
                    }

                    var rockFile = new Rock.Model.BinaryFile
                    {
                        IsSystem               = false,
                        IsTemporary            = false,
                        MimeType               = GetMIMEType(file.Name),
                        BinaryFileTypeId       = attributeBinaryFileType.Id,
                        FileName               = file.Name,
                        Description            = string.Format("Imported as {0}", file.Name),
                        CreatedDateTime        = file.LastWriteTime.DateTime,
                        ModifiedDateTime       = file.LastWriteTime.DateTime,
                        CreatedByPersonAliasId = ImportPersonAliasId,
                        ForeignKey             = documentForeignId,
                        ForeignId              = documentForeignId.AsIntegerOrNull()
                    };

                    rockFile.SetStorageEntityTypeId(attributeBinaryFileType.StorageEntityTypeId);
                    rockFile.StorageEntitySettings = emptyJsonObject;

                    if (attributeBinaryFileType.AttributeValues != null)
                    {
                        rockFile.StorageEntitySettings = attributeBinaryFileType.AttributeValues
                                                         .ToDictionary(a => a.Key, v => v.Value.Value).ToJson();
                    }

                    // use base stream instead of file stream to keep the byte[]
                    // NOTE: if byte[] converts to a string it will corrupt the stream
                    using (var fileContent = new StreamReader(file.Open()))
                    {
                        rockFile.ContentStream = new MemoryStream(fileContent.BaseStream.ReadBytesToEnd());
                    }

                    newFileList.Add(new DocumentKeys()
                    {
                        PersonId    = personKeys.PersonId,
                        AttributeId = fileAttribute.Id,
                        File        = rockFile
                    });

                    completedItems++;

                    if (completedItems % percentage < 1)
                    {
                        var percentComplete = completedItems / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} ministry document files imported ({1}% complete).", completedItems, percentComplete));
                    }

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveFiles(newFileList);

                        // Reset list
                        newFileList.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newFileList.Any())
            {
                SaveFiles(newFileList);
            }

            ReportProgress(100, string.Format("Finished documents import: {0:N0} ministry documents imported.", completedItems));
            return(completedItems);
        }