public IHttpActionResult UploadResource()
        {
            //throw new Exception("forced error");
            HttpResponseMessage response = new HttpResponseMessage();
            var             httpRequest  = HttpContext.Current.Request;
            DigitalResource myResource   = null;

            //DigitalResource resource = null;
            //if (albumID != null)
            {
                System.Web.HttpFileCollection files         = System.Web.HttpContext.Current.Request.Files;
                Repository.ResourceRepository repository    = new Repository.ResourceRepository();
                ReferenceRepository           refRepository = new ReferenceRepository();
                UserRepository ur          = new UserRepository();
                string         currentUser = User.Identity.Name;
                User           user        = ur.Get(currentUser);
                //Album album = repository.GetAlbums(x => x.Name == albumID).FirstOrDefault();

                //for (int i = 0; i < files.Count; i++)
                {
                    HttpPostedFile file = files[0];

                    string name = file.FileName;
                    using (Stream fileStream = file.InputStream)
                    {
                        myResource = repository.SaveOrGet(refRepository, user, fileStream, name);
                    }
                }
            }

            return(Ok(myResource));
        }
        /// <summary>
        /// get the album resource from the database if it exists. If it does not exist,
        /// get the album and the resource and put them into a new AlbumResource
        /// </summary>
        /// <param name="albumID"></param>
        /// <param name="resourceGUID"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public AlbumResource GetOrCreateAlbumResource(int albumID, string resourceGUID, string userName)
        {
            AlbumResource albumResource  = null;
            var           sessionFactory = SessionFactoryCreator.CreateSessionFactory();

            using (var session = sessionFactory.OpenSession())
            {
                using (session.BeginTransaction())
                {
                    albumResource = session.QueryOver <AlbumResource>()
                                    .Where(x => x.Album.ID == albumID && x.Resource.Md5 == resourceGUID)
                                    .List().FirstOrDefault();

                    if (albumResource == null)
                    {
                        Album album = session.QueryOver <Album>()
                                      .Where(x => x.ID == albumID)
                                      .JoinQueryOver(x => x.Owner)
                                      .Where(x => x.UserName == userName)
                                      .List().FirstOrDefault();
                        DigitalResource resource = Get(resourceGUID, userName);

                        albumResource = new AlbumResource
                        {
                            Album    = album,
                            Resource = resource
                        };
                    }
                }
            }
            return(albumResource);
        }
        public void AddTag(string resourceID, string tag)
        {
            UserRepository ur       = new UserRepository();
            string         username = User.Identity.Name;
            User           user     = ur.Get(username);

            Repository.ResourceRepository repository = new Repository.ResourceRepository();
            TagRepository tagRepository = new TagRepository();

            DigitalResource resource = repository.Get(resourceID, user);

            ResourceModel.Tag tagToAdd = tagRepository.GetOrAdd(tag);

            resource.AddTag(tagToAdd);
        }
        private static MediaTypeHeaderValue GetMediaType(DigitalResource resource)
        {
            String ext = String.Empty;

            if (resource.OriginalFileName.Contains("."))
            {
                ext = resource.OriginalFileName.Substring(resource.OriginalFileName.IndexOf(".") + 1);
            }
            if (String.IsNullOrEmpty(ext))
            {
                ext = "application/octet-stream";
            }
            string mimeType = MimeTypeHelper.GetMimeType(ext);
            MediaTypeHeaderValue _mediaType = MediaTypeHeaderValue.Parse(mimeType);

            return(_mediaType);
        }
        public bool Exists(string md5)
        {
            DigitalResource resource = null;// list = new List<Resource>();

            var sessionFactory = SessionFactoryCreator.CreateSessionFactory();

            using (var session = sessionFactory.OpenSession())
            {
                using (session.BeginTransaction())
                {
                    //session.CreateCriteria(typeof(DigitalResource)).ToList();
                    resource = session.QueryOver <DigitalResource>()
                               .Where(x => x.Md5 == md5)
                               .List().FirstOrDefault();
                }
            }
            return(resource != null);
        }
        public IHttpActionResult Upload(string albumID)
        {
            //throw new Exception("forced error");
            HttpResponseMessage response = new HttpResponseMessage();
            var             httpRequest  = HttpContext.Current.Request;
            DigitalResource myResource   = null;

            //DigitalResource resource = null;
            if (albumID != null)
            {
                System.Web.HttpFileCollection files         = System.Web.HttpContext.Current.Request.Files;
                Repository.ResourceRepository repository    = new Repository.ResourceRepository();
                ReferenceRepository           refRepository = new ReferenceRepository();
                UserRepository ur       = new UserRepository();
                string         username = User.Identity.Name;
                User           user     = ur.Get(username);
                Album          album    = repository.GetAlbums(x => x.Name == albumID).FirstOrDefault();

                //for (int i = 0; i < files.Count; i++)
                {
                    HttpPostedFile file = files[0];

                    string name = file.FileName;
                    using (Stream fileStream = file.InputStream)
                    {
                        myResource = repository.SaveOrGet(refRepository, user, fileStream, name);
                        if (myResource != null)
                        {
                            album.AddResource(myResource);
                            repository.SaveAlbum(album);
                        }
                        //resource = myResource;
                        //response.Content = new StringContent("{\"Md5\": \""+ "12345" + "\"");
                        //response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    }
                }
            }

            return(Ok(myResource));
        }
        /// <summary>
        /// Saves a NEW resource. Only saves if resource with the MD5Sum has not previously been added.
        /// </summary>
        /// <param name="referenceRepository"></param>
        /// <param name="fileStream"></param>
        /// <param name="originalName"></param>
        /// <returns>the AWS Upload ID</returns>
        public async Task <string> UploadPartial(ResourceModel.User owner,
                                                 string md5OfResource,
                                                 string uploadIdentifier,
                                                 Stream fileStream,
                                                 int partNumber,
                                                 int numberOfParts)
        {
            ResourceModel.DigitalResource resource = null;
            //User user = reference

            try
            {
                //bool exists = Exists(md5Sum);
                DigitalResource existingResource = Get(md5OfResource);
                if (existingResource == null)
                {
                    //fileStream.Position = 0;
                    //TransferUtilityUploadRequest tuu = new TransferUtilityUploadRequest
                    //{
                    //    InputStream = fileStream,
                    //    BucketName = "piccoli",
                    //    Key = "belvedere"
                    //};
                    //tr.UploadAsync(tuu);

                    //upload the file
                    IAmazonS3 s3Client = new AmazonS3Client();
                    //ListBucketsResponse response = s3Client.ListBuckets();

                    //https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TUploadPartResponse.html
                    //https://docs.aws.amazon.com/AmazonS3/latest/dev/LLuploadFileDotNet.html
                    string uploadID = uploadIdentifier;
                    if (partNumber == 1)
                    {
                        InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
                        {
                            BucketName = "piccoli",
                            Key        = md5OfResource,
                        };

                        // Initiate the upload.
                        InitiateMultipartUploadResponse initResponse =
                            await s3Client.InitiateMultipartUploadAsync(initiateRequest);

                        uploadID = initResponse.UploadId;
                    }
                    // Upload part X
                    UploadPartRequest uploadRequest = new UploadPartRequest
                    {
                        BucketName  = "piccoli",
                        Key         = md5OfResource,
                        UploadId    = uploadID,
                        PartNumber  = partNumber,
                        PartSize    = fileStream.Length, //5242880,//5MB ?
                        InputStream = fileStream
                    };
                    UploadPartResponse response = s3Client.UploadPart(uploadRequest);
                    return(uploadID);
                }
                return("resource already exists");
            }
            catch (AmazonS3Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Saves a NEW resource. Only saves if resource with the MD5Sum has not previously been added.
        /// </summary>
        /// <param name="referenceRepository"></param>
        /// <param name="fileStream"></param>
        /// <param name="originalName"></param>
        /// <returns>DigitalResource with the length of the file. The Digital Resource may
        /// be newly created OR retrieved from the database if it already exists</returns>
        public ResourceModel.DigitalResource SaveOrGet(ReferenceRepository referenceRepository,
                                                       ResourceModel.User owner,
                                                       Stream fileStream,
                                                       String originalName)
        {
            ResourceModel.DigitalResource resource = null;
            ResourceType imageRT = referenceRepository.AllResourceTypes().Where(x => x.Type == "Image").FirstOrDefault();
            ResourceType otherRT = referenceRepository.AllResourceTypes().Where(x => x.Type == "Other").FirstOrDefault();

            //User user = reference

            try
            {
                //calculate md5 of the file to upload
                string md5Sum = Md5Hash(fileStream);

                //bool exists = Exists(md5Sum);
                DigitalResource existingResource = Get(md5Sum);
                if (existingResource == null)
                {
                    //create the resource object
                    resource = new ResourceModel.DigitalResource
                    {
                        Md5 = md5Sum,
                        OriginalFileName = originalName,
                        Size             = fileStream.Length,
                        Uploaded         = DateTime.Now,
                        Owners           = new List <ResourceModel.User>()
                    };

                    resource.Owners.Add(owner);

                    if (ReferenceService.IsValidImage(fileStream))
                    {
                        resource.Type = imageRT;
                        //resource.Type = "Image";
                        resource.Date = ReferenceService.GetDateTakenFromImage(fileStream);
                    }
                    else
                    {
                        resource.Type = otherRT;
                        resource.Date = null;
                    }

                    //fileStream.Position = 0;
                    //TransferUtilityUploadRequest tuu = new TransferUtilityUploadRequest
                    //{
                    //    InputStream = fileStream,
                    //    BucketName = "piccoli",
                    //    Key = "belvedere"
                    //};
                    //tr.UploadAsync(tuu);

                    //upload the file
                    IAmazonS3 s3Client = new AmazonS3Client();
                    //ListBucketsResponse response = s3Client.ListBuckets();

                    using (TransferUtility tr = new TransferUtility(s3Client))
                    {
                        tr.Upload(fileStream, "piccoli", md5Sum);
                        //update the database
                        SaveResource(resource);
                    }
                }
                else
                {
                    //another user also has a copy of this file
                    if (existingResource.Owners.Where(x => x.UserName == owner.UserName).FirstOrDefault() == null)
                    {
                        existingResource.Owners.Add(owner);

                        SaveResource(existingResource);
                    }

                    return(existingResource);
                }
            }
            catch (AmazonS3Exception ex)
            {
                throw ex;
            }

            return(resource);
        }
        public bool ResourceExists(String hashID, ResourceModel.User user)
        {
            DigitalResource resource = Get(hashID, user);

            return(resource != null);
        }
        public async Task <HttpResponseMessage> Get(string id)
        {
            bool isPartial = false;

            UserRepository ur       = new UserRepository();
            string         username = User.Identity.Name;
            User           user     = ur.Get(username);

            Repository.ResourceRepository repository = new Repository.ResourceRepository();
            DigitalResource resource = repository.Get(id, user);
            //await stream.CopyToAsync(stream2,);
            // Create a client
            AmazonS3Client client = new AmazonS3Client();

            long from = 0;
            long to   = 0;

            GetObjectRequest request = null;

            if (Request.Headers.Range != null)
            {
                isPartial = true;
                //If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the entity-body,
                //last -byte-pos is taken to be equal to one less than the current length of the entity- body in bytes.
                //*-The final 500 bytes(byte offsets 9500 - 9999, inclusive):
                //    bytes = -500
                //  - Or bytes = 9500 -
                if (Request.Headers.Range.Ranges.First().From == null)
                {
                    from = (resource.Size - 1) - (long)Request.Headers.Range.Ranges.First().To;
                }
                else //From byte is specified
                {
                    from = (long)Request.Headers.Range.Ranges.First().From;
                }

                to = resource.Size - 1;
                if (Request.Headers.Range.Ranges.First().To != null)
                {
                    to = (long)Request.Headers.Range.Ranges.First().To;
                }
                else//Chrome often sends out a 0- request. Instead of passing back a massive file, just pass back the first 500 bytes
                {
                    if (from == 0)
                    {
                        to = 499;
                    }
                }
                request = new GetObjectRequest
                {
                    BucketName = "piccoli",
                    Key        = id,
                    ByteRange  = new ByteRange(from, to)
                };
            }
            else
            {
                request = new GetObjectRequest
                {
                    BucketName = "piccoli",
                    Key        = id
                };
            }
            // Issue request and remember to dispose of the response
            //using
            GetObjectResponse   response = client.GetObject(request);
            HttpStatusCode      status   = isPartial ? HttpStatusCode.PartialContent : HttpStatusCode.OK;
            HttpResponseMessage result   = new HttpResponseMessage(status);

            result.Content = new StreamContent(response.ResponseStream);
            string contentType = response.Headers["Content-Type"];

            result.Content.Headers.ContentLength = resource.Size;
            if (isPartial)
            {
                result.Content.Headers.ContentLength = to - from + 1;//resource.Size;
                result.Content.Headers.ContentRange  = new ContentRangeHeaderValue(from, to, resource.Size);
            }
            result.Content.Headers.ContentType =
                new MediaTypeHeaderValue(contentType);//contentType);
            return(result);
        }
        public HttpResponseMessage GetThumbnailRepresentation(string id)
        {
            UserRepository ur       = new UserRepository();
            string         username = User.Identity.Name;
            User           user     = ur.Get(username);

            int thumbnailHeight = 120;

            Repository.ResourceRepository repository = new Repository.ResourceRepository();
            DigitalResource resource = repository.Get(id, user);
            string          mimeType = String.Empty;

            if (resource.OriginalFileName.IndexOf(".") > 0)
            {
                string extension = resource.OriginalFileName.Substring(resource.OriginalFileName.LastIndexOf(".") + 1);
                mimeType = MimeTypeHelper.GetMimeType(resource.OriginalFileName.Substring(resource.OriginalFileName.LastIndexOf(".") + 1));
            }

            //await stream.CopyToAsync(stream2,);
            // Create a client
            AmazonS3Client client = new AmazonS3Client();

            GetObjectRequest request = null;

            request = new GetObjectRequest
            {
                BucketName = "piccoli",
                Key        = id
            };

            // Issue request and remember to dispose of the response
            //using
            GetObjectResponse   response = client.GetObject(request);
            HttpResponseMessage result   = new HttpResponseMessage(HttpStatusCode.OK);


            if (mimeType.Contains("image"))
            {
                Image myImage = Image.FromStream(response.ResponseStream);

                float        multiplicationRatio = (float)thumbnailHeight / (float)myImage.Height;
                int          thumbnailWidth      = (int)(multiplicationRatio * myImage.Width);
                Bitmap       bmp          = ResizeImage(myImage, thumbnailWidth, thumbnailHeight);
                MemoryStream memoryStream = new MemoryStream();
                bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                memoryStream.Position = 0;
                result.Content        = new StreamContent(memoryStream);
                result.Content.Headers.ContentType =
                    new MediaTypeHeaderValue("application/octet-stream");
            }
            //else if (mimeType.Contains("video"))
            //{
            //    VideoFileReader reader = new VideoFileReader();
            //    reader.
            //    Bitmap bmp = reader.ReadVideoFrame();
            //    MemoryStream memoryStream = new MemoryStream();
            //    bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            //    memoryStream.Position = 0;
            //    result.Content = new StreamContent(memoryStream);
            //    result.Content.Headers.ContentType =
            //        new MediaTypeHeaderValue("application/octet-stream");
            //}
            else
            {
                MemoryStream memoryStream = TextToImage(200, 120, "Non image resource");
                result.Content = new StreamContent(memoryStream);
                result.Content.Headers.ContentType =
                    new MediaTypeHeaderValue("application/octet-stream");
            }

            return(result);
        }