示例#1
0
        public async Task <ImageFileIdentity> AddImage(Stream imageFileStream, FileName imageFileName, FileFormat fileFormat)
        {
            var imageFileIdentity = ImageFileIdentity.New();

            // Get unique file-name from image file identity.
            var uniqueImageFileName = imageFileIdentity.GetUniqueFileName();

            // Get the storage file path of the image file, using a single directory path and a globally-unique file name.
            var uniqueImageFilePath = this.GetUniqueImageFilePath(uniqueImageFileName);

            // Write the image file from its input stream to its unique local file path.
            using (var file = File.Open(uniqueImageFilePath.Value, FileMode.CreateNew)) // Throw an exception if the file already exists by using create-new.
            {
                await imageFileStream.CopyToAsync(file);
            }

            // Add the file info to the repository.
            var fileIdentity = imageFileIdentity.GetFileIdentity();

            var fileInfo = new FileInfoAppType()
            {
                FileIdentity = fileIdentity,
                FilePath     = uniqueImageFilePath,
                FileFormat   = fileFormat,
            };

            await this.LocalFileInfoRepository.Add(fileInfo);

            // Now add the unique file-name to original file-name mapping.
            await this.OriginalFileNameMappingRepository.Add(uniqueImageFileName, imageFileName);

            // Return the image file identity.
            return(imageFileIdentity);
        }
示例#2
0
        public async Task AddImageFile(AnomalyIdentity anomalyIdentity, ImageFileIdentity imageFileIdentity)
        {
            await this.ExecuteInContextAsync(async dbContext =>
            {
                var anomalyID = await dbContext.GetAnomaly(anomalyIdentity).Select(x => x.ID).SingleAsync();

                // Acquire the AnomalyToImageFileMapping (since there currently can only be one image per anomaly).
                var anomalyToImageFileMappingEntity = await dbContext.AnomalyToImageFileMappings.Where(x => x.AnomalyID == anomalyID).SingleOrDefaultAsync();
                var existsAlready = anomalyToImageFileMappingEntity is object;
                if (existsAlready)
                {
                    anomalyToImageFileMappingEntity.ImageFileGUID = imageFileIdentity.Value;
                }
                else
                {
                    anomalyToImageFileMappingEntity = new Entities.AnomalyToImageFileMapping()
                    {
                        AnomalyID     = anomalyID,
                        ImageFileGUID = imageFileIdentity.Value,
                    };

                    dbContext.AnomalyToImageFileMappings.Add(anomalyToImageFileMappingEntity);
                }

                await dbContext.SaveChangesAsync();
            });
        }
示例#3
0
        public Task <Dictionary <AnomalyIdentity, List <ImageFileIdentity> > > GetImageFilesForAnomalies(IEnumerable <AnomalyIdentity> anomalyIdentities)
        {
            return(this.ExecuteInContext(async dbContext =>
            {
                var anomalyGuids = anomalyIdentities.Select(x => x.Value).ToList();

                var query = from anomaly in dbContext.Anomalies
                            where anomalyGuids.Contains(anomaly.GUID)
                            join anomalyImage in dbContext.AnomalyToImageFileMappings
                            on anomaly.ID equals anomalyImage.AnomalyID into imageGroup
                            from i in imageGroup.DefaultIfEmpty()
                            select new
                {
                    anomaly.GUID,
                    ImageIdentity = i == default ? Guid.Empty : i.ImageFileGUID,
                };

                var result = await query.ToListAsync();

                // Group it by anomaly (since we need an AnomalyInfo per AnomalyIdentity passed in)
                var grouped = result.GroupBy(
                    x => AnomalyIdentity.From(x.GUID),
                    x => ImageFileIdentity.From(x.ImageIdentity));

                var output = grouped.ToDictionary(
                    grouping => grouping.Key,
                    grouping => grouping
                    .Where(x => !x.IsEmpty())
                    .ToList());

                return output;
            }));
        }
示例#4
0
        private FilePath GetUniqueImageFilePath(ImageFileIdentity imageFileIdentity)
        {
            var uniqueImageFileName = imageFileIdentity.GetUniqueFileName();

            var uniqueImageFilePath = this.GetUniqueImageFilePath(uniqueImageFileName);

            return(uniqueImageFilePath);
        }
示例#5
0
        public async Task <FileFormat> GetImageFileFormat(ImageFileIdentity imageFileIdentity)
        {
            var fileIdentity = imageFileIdentity.GetFileIdentity();

            var fileFormat = await this.LocalFileInfoRepository.GetFileFormat(fileIdentity);

            return(fileFormat);
        }
示例#6
0
        public static FileName GetUniqueFileName(this ImageFileIdentity imageFileIdentity)
        {
            var uniqueFileNameValue = imageFileIdentity.GetUniqueFileNameValue();

            var uniqueFileName = FileName.New(uniqueFileNameValue);

            return(uniqueFileName);
        }
示例#7
0
        public async Task <bool> Exists(ImageFileIdentity imageFileIdentity)
        {
            var fileIdentity = imageFileIdentity.GetFileIdentity();

            var exists = await this.LocalFileInfoRepository.Exists(fileIdentity);

            return(exists);
        }
示例#8
0
        /// <summary>
        /// This, in context, means the original image file name.
        /// </summary>
        public async Task <FileName> GetImageFileName(ImageFileIdentity imageFileIdentity)
        {
            // Can get the unique image file-name directly from the image file identity.
            var uniqueImageFileName = imageFileIdentity.GetUniqueFileName();

            var originalImageFileName = await this.OriginalFileNameMappingRepository.GetOriginalImageFileName(uniqueImageFileName);

            return(originalImageFileName);
        }
示例#9
0
        public async Task SetImageData(ImageFileIdentity imageFileIdentity, Stream imageFileStream)
        {
            var uniqueImageFilePath = this.GetUniqueImageFilePath(imageFileIdentity);

            // Overwrite.
            using (var file = File.OpenWrite(uniqueImageFilePath.Value))
            {
                await imageFileStream.CopyToAsync(file);
            }
        }
示例#10
0
        public async Task <List <ImageFileIdentity> > GetImageFiles(AnomalyIdentity anomalyIdentity)
        {
            var imageFileIdentities = await this.ExecuteInContextAsync(async dbContext =>
            {
                var imageFileGuids = dbContext.AnomalyToImageFileMappings.Where(x => x.Anomaly.GUID == anomalyIdentity.Value).Select(x => x.ImageFileGUID);

                var output = await imageFileGuids.Select(x => ImageFileIdentity.From(x)).ToListAsync(); // Execute now.
                return(output);
            });

            return(imageFileIdentities);
        }
示例#11
0
        public Task <Stream> GetImageFileStream(ImageFileIdentity imageFileIdentity)
        {
            var uniqueImageFilePath = this.GetUniqueImageFilePath(imageFileIdentity);

            // For times when the file doesn't exist (particularly common in dev, but happens in prod too)
            // return a null stream. And hope for the best from there.
            if (!File.Exists(uniqueImageFilePath.Value))
            {
                return(Task.FromResult <Stream>(Stream.Null));
            }
            var imageFileStream = File.OpenRead(uniqueImageFilePath.Value);

            return(Task.FromResult <Stream>(imageFileStream));
        }
示例#12
0
        public async Task <ImageFileReadInfo> GetReadInfo(ImageFileIdentity imageFileIdentity)
        {
            var getImageFileStream = this.GetImageFileStream(imageFileIdentity);
            var getImageFileName   = this.GetImageFileName(imageFileIdentity);
            var getImageFileFormat = this.GetImageFileFormat(imageFileIdentity);

            var imageFileStream       = await getImageFileStream;
            var originalImageFileName = await getImageFileName;
            var imageFileFormat       = await getImageFileFormat;

            var readInfo = new ImageFileReadInfo()
            {
                Identity   = imageFileIdentity,
                Stream     = imageFileStream,
                FileName   = originalImageFileName,
                FileFormat = imageFileFormat,
            };

            return(readInfo);
        }
示例#13
0
        public async Task Delete(ImageFileIdentity imageFileIdentity)
        {
            var uniqueImageFileName = imageFileIdentity.GetUniqueFileName();
            var uniqueImageFilePath = this.GetUniqueImageFilePath(uniqueImageFileName);

            // The multiple tasks are sequentially awaited to allow failures to preserve the sequence of events in case of failure.
            // (The alternative would have been to Task.WhenAll() the various tasks, which would be simultaneous, but would lead to situations where things might get out of whack in case of failure.)

            // Delete the image file.
            await FileHelper.DeleteAsync(uniqueImageFilePath.Value);

            // Remove the local file info.
            var fileIdentity = imageFileIdentity.GetFileIdentity();

            await this.LocalFileInfoRepository.Delete(fileIdentity);

            // Delete the original image name mapping.

            await this.OriginalFileNameMappingRepository.Delete(uniqueImageFileName);
        }
示例#14
0
        public async Task <AnomalyInfo> GetAnomalyInfo(AnomalyIdentity anomalyIdentity)
        {
            var anomalyInfo = await this.ExecuteInContextAsync(async dbContext =>
            {
                var gettingAnomalyDetails = dbContext.GetAnomaly(anomalyIdentity)
                                            .Select(x => new
                {
                    x.ReportedUTC,
                    x.ReportedLocationGUID,
                    x.ReporterLocationGUID,
                    x.UpvotesCount,
                })
                                            .SingleAsync();

                var gettingImageFileIdentityValues = dbContext.GetAnomaly(anomalyIdentity)
                                                     .Join(dbContext.AnomalyToImageFileMappings,
                                                           anomaly => anomaly.ID,
                                                           mapping => mapping.AnomalyID,
                                                           (_, mapping) => mapping.ImageFileGUID)
                                                     .ToListAsync();

                var gettingTextItemIdentityValues = dbContext.GetAnomaly(anomalyIdentity)
                                                    .Join(dbContext.AnomalyToTextItemMappings,
                                                          anomaly => anomaly.ID,
                                                          mapping => mapping.AnomalyID,
                                                          (_, mapping) => mapping.TextItemGUID)
                                                    .ToListAsync();

                var gettingCatchmentMapping = dbContext.GetAnomaly(anomalyIdentity)
                                              .Join(dbContext.AnomalyToCatchmentMappings,
                                                    anomaly => anomaly.ID,
                                                    mapping => mapping.AnomalyID,
                                                    (_, mapping) => mapping)
                                              .ToListAsync();


                var anomalyDetails          = await gettingAnomalyDetails;
                var imageFileIdentityValues = await gettingImageFileIdentityValues;
                var textItemIdentityValues  = await gettingTextItemIdentityValues;
                var catchmentMapping        = await gettingCatchmentMapping;

                var catchmentIdentities = catchmentMapping.Select(x => CatchmentIdentity.From(x.CatchmentIdentity)).ToList();
                var imageFileIdentities = imageFileIdentityValues.Select(x => ImageFileIdentity.From(x)).ToList();
                var reportedLocation    = anomalyDetails.ReportedLocationGUID.HasValue ? LocationIdentity.From(anomalyDetails.ReportedLocationGUID.Value) : null;
                var reporterLocation    = anomalyDetails.ReporterLocationGUID.HasValue ? LocationIdentity.From(anomalyDetails.ReporterLocationGUID.Value) : null;
                var reportedUTC         = anomalyDetails.ReportedUTC;
                var textItems           = textItemIdentityValues.Select(x => TextItemIdentity.From(x)).ToList();
                var upvotesCount        = anomalyDetails.UpvotesCount;

                var output = new AnomalyInfo()
                {
                    AnomalyIdentity          = anomalyIdentity,
                    CatchmentIdentities      = catchmentIdentities,
                    ImageFileIdentities      = imageFileIdentities,
                    ReportedLocationIdentity = reportedLocation,
                    ReporterLocationIdentity = reporterLocation,
                    ReportedUTC         = reportedUTC,
                    TextItemsIdentities = textItems,
                    UpvotesCount        = upvotesCount,
                };
                return(output);
            });

            return(anomalyInfo);
        }
示例#15
0
        public static string GetUniqueFileNameValue(this ImageFileIdentity imageFileIdentity)
        {
            var uniqueFileNameValue = imageFileIdentity.Value.ToStringStandard();

            return(uniqueFileNameValue);
        }
示例#16
0
        public static FileIdentity GetFileIdentity(this ImageFileIdentity imageFileIdentity)
        {
            var fileIdentity = FileIdentity.New(imageFileIdentity.Value);

            return(fileIdentity);
        }
示例#17
0
        public async Task <List <AnomalyInfo> > GetAnomalyInfos(List <AnomalyIdentity> anomalyIdentities)
        {
            var anomalyGuids = anomalyIdentities.Select(x => x.Value).ToList();
            var output       = await this.ExecuteInContextAsync(async dbContext =>
            {
                // Get all the info, in rows.
                var query =
                    from anomaly in dbContext.Anomalies
                    where anomaly.GUID != null
                    where anomalyGuids.Contains(anomaly.GUID)
                    join anomalyCatchment in dbContext.AnomalyToCatchmentMappings
                    on anomaly.ID equals anomalyCatchment.AnomalyID into catchmentGroup
                    from c in catchmentGroup.DefaultIfEmpty()
                    join anomalyText in dbContext.AnomalyToTextItemMappings
                    on anomaly.ID equals anomalyText.AnomalyID into textGroup
                    from t in textGroup.DefaultIfEmpty()
                    join anomalyImage in dbContext.AnomalyToImageFileMappings
                    on anomaly.ID equals anomalyImage.AnomalyID into imageGroup
                    from i in imageGroup.DefaultIfEmpty()
                    select new
                {
                    anomaly.ID,
                    anomaly.GUID,
                    anomaly.ReportedUTC,
                    anomaly.ReportedLocationGUID,
                    anomaly.ReporterLocationGUID,
                    CatchmentIdentity = c == default ? Guid.Empty : c.CatchmentIdentity,
                    TextItemIdentity  = t == default ? Guid.Empty : t.TextItemGUID,
                    ImageIdentity     = i == default ? Guid.Empty : i.ImageFileGUID,
                };
                // Group it by anomaly (since we need an AnomalyInfo per AnomalyIdentity passed in)
                var result  = await query.ToListAsync();
                var grouped = result.GroupBy(group =>
                                             new {
                    group.ID,
                    group.GUID,
                    group.ReportedUTC,
                    group.ReportedLocationGUID,
                    group.ReporterLocationGUID
                }, group => group);

                // Use the grouping to put together anomaly infos.
                var anomalyInfos = new List <AnomalyInfo>();
                foreach (var entry in grouped)
                {
                    // Console.WriteLine(entry.Key);
                    var images      = new HashSet <Guid>();
                    var catchments  = new HashSet <Guid>();
                    var textItemSet = new HashSet <Guid>();
                    foreach (var thing in entry)
                    {
                        images.Add(thing.ImageIdentity);
                        catchments.Add(thing.CatchmentIdentity);
                        textItemSet.Add(thing.TextItemIdentity);
                    }

                    var imagesList     = images.ToList();
                    var catchmentsList = catchments.ToList();
                    var textItemsList  = textItemSet.ToList();

                    // Console.WriteLine($"    Images ({images.Count}):     {string.Join(',',images.ToList())}");
                    // Console.WriteLine($"    Catchments ({catchments.Count}): {string.Join(',', catchments.ToList())}");
                    // Console.WriteLine($"    Text items ({textItemSet.Count}): {string.Join(',', textItemSet.ToList())}");

                    if (entry.Key.GUID == default)
                    {
                        // Unfortunately this also catches anomalies added with an all-zeros guid...
                        // and we have at least one of those (ID 228 as of 2020-07-17)
                        // throw new Exception("Got an anomaly without a GUID");
                    }
                    var anomalyIdentity     = new AnomalyIdentity(entry.Key.GUID);
                    var reportedUTC         = entry.Key.ReportedUTC;
                    var reportedLocation    = entry.Key.ReportedLocationGUID.HasValue ? LocationIdentity.From(entry.Key.ReportedLocationGUID.Value) : null;
                    var reporterLocation    = entry.Key.ReporterLocationGUID.HasValue ? LocationIdentity.From(entry.Key.ReporterLocationGUID.Value) : null;
                    var catchmentIdentities = catchmentsList.Select(x => CatchmentIdentity.From(x)).ToList();
                    var imageFileIdentities = imagesList
                                              .Where(x => x != Guid.Empty)
                                              .Select(x => ImageFileIdentity.From(x))
                                              .ToList();
                    var textItems = textItemsList.Select(x => TextItemIdentity.From(x)).ToList();
                    var info      = new AnomalyInfo
                    {
                        AnomalyIdentity          = anomalyIdentity,
                        ReportedUTC              = reportedUTC,
                        ReportedLocationIdentity = reportedLocation,
                        ReporterLocationIdentity = reporterLocation,
                        CatchmentIdentities      = catchmentIdentities,
                        ImageFileIdentities      = imageFileIdentities,
                        TextItemsIdentities      = textItems
                    };
                    anomalyInfos.Add(info);
                }
                return(anomalyInfos);
            });

            return(output);
        }