Exemplo n.º 1
0
        // Proto to domain
        public static FileItem Convert(this gFileItem file)
        {
            if (file == null)
            {
                return(new FileItem());
            }

            var status = file.Status switch
            {
                Protos.ItemStatus.Visible => Domain.ItemStatus.Visible,
                Protos.ItemStatus.Hidden => Domain.ItemStatus.Hidden,
                Protos.ItemStatus.ToBeProcessed => Domain.ItemStatus.To_Be_Processed,
                Protos.ItemStatus.ToBeDeleted => Domain.ItemStatus.To_Be_Deleted,
                _ => Domain.ItemStatus.Visible,
            };

            return(new FileItem()
            {
                Id = file.Id,
                TusId = file.TusId,
                UserId = file.UserId,
                Size = file.Size,
                Name = file.Name,
                MimeType = file.MimeType,
                FolderId = file.FolderId,
                Extension = file.Extension,
                CreatedAt = file.CreatedAt.ToDateTime(),
                LastModified = file.LastModified.ToDateTime(),
                Status = status,
                StorageServerId = Guid.Parse(file.StorageServerId),
            });
        }
Exemplo n.º 2
0
        /// <summary>
        /// Persist the uploaded file data to db
        /// </summary>
        private async Task <gFileItem> PersistMetaData(FileCompleteContext ctx)
        {
            var gUserResponse = await _fileMngClient.GetUserAsync(new gUserRequest());

            if (gUserResponse == null)
            {
                _logger.LogError("Unknown error occured while requesting user info");
                ctx.HttpContext.Response.StatusCode = 400;
                return(null);
            }
            if (gUserResponse.Status.Status != Protos.RequestStatus.Success)
            {
                _logger.LogError(gUserResponse.Status.Message);
                ctx.HttpContext.Response.StatusCode = 400;
                return(null);
            }

            ITusFile file     = await((ITusReadableStore)ctx.Store).GetFileAsync(ctx.FileId, ctx.CancellationToken);
            var      metadata = await file.GetMetadataAsync(ctx.CancellationToken);

            gFileItem fileitem = new gFileItem()
            {
                Id       = Helpers.GenerateUniqueId(),
                TusId    = ctx.FileId,
                UserId   = gUserResponse.User.Id,
                Size     = uint.Parse(new FileInfo(Path.Combine(_uploadOpts.CurrentValue.UploadPath, file.Id)).Length.ToString()),
                Name     = metadata["name"].GetString(Encoding.UTF8),
                MimeType = metadata["contentType"].GetString(Encoding.UTF8),
                // file with no folderid is placed in the virtual root folder
                FolderId = metadata["folderId"].GetString(Encoding.UTF8) == "root"
                                                                                ? null
                                                                                : metadata["folderId"].GetString(Encoding.UTF8),
                Extension       = Helpers.GetFileExtension(metadata["contentType"].GetString(Encoding.UTF8)) ?? string.Empty,
                StorageServerId = metadata["serverId"].GetString(Encoding.UTF8),
                CreatedAt       = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                LastModified    = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                Status          = Protos.ItemStatus.Visible
            };

            // send the uploaded file info to the main app
            gFileItemResponse response = await _fileMngClient.SaveFileAsync(new gFileItemRequest()
            {
                FileItem = fileitem
            });

            if (response == null)
            {
                _logger.LogError("No response has been received from the server.", ErrorOrigin.Server);
                return(null);
            }
            if (response.Status.Status != Protos.RequestStatus.Success)
            {
                _logger.LogError("An error has been returned from server call: " + response.Status.Message);
                return(null);
            }
            return(response.FileItem);
        }
        /// <summary>
        /// Get the response header made by the current http request.
        /// download request can be resumed, so correct header must be set
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <param name="fileInfo"></param>
        /// <returns></returns>
        private HttpResponseHeader GetResponseHeader(gFileItem file)
        {
            if (_httpContext.Request == null || file == null)
            {
                return(null);
            }

            long   startPosition = 0;
            string contentRange  = "";

            string fileName          = file.Name;
            long   fileLength        = file.Size;
            string lastUpdateTimeStr = file.LastModified.ToString();

            string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + " " + lastUpdateTimeStr;
            string contentDisposition = "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20");

            if (_httpContext.Request.Headers["Range"] != StringValues.Empty)
            {
                string[] range = _httpContext.Request.Headers["Range"].ToString().Split(new char[] { '=', '-' });
                startPosition = Convert.ToInt64(range[1]);
                if (startPosition < 0 || startPosition >= fileLength)
                {
                    return(null);
                }
            }

            if (_httpContext.Request.Headers["If-Range"].ToString() != null)
            {
                if (_httpContext.Request.Headers["If-Range"].ToString().Replace("\"", "") != eTag)
                {
                    startPosition = 0;
                }
            }

            string contentLength = (fileLength - startPosition).ToString();

            if (startPosition > 0)
            {
                contentRange = string.Format(" bytes {0}-{1}/{2}", startPosition, fileLength - 1, fileLength);
            }

            HttpResponseHeader responseHeader = new HttpResponseHeader
            {
                AcceptRanges       = "bytes",
                Connection         = "Keep-Alive",
                ContentDisposition = contentDisposition,
                ContentEncoding    = Encoding.UTF8,
                ContentLength      = contentLength,
                ContentRange       = contentRange,
                ContentType        = "application/octet-stream",
                Etag         = eTag,
                LastModified = lastUpdateTimeStr
            };

            return(responseHeader);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Moves the uploaded files (the actual file and it's metadata) to the user folder
        /// tus protocol puts the uploaded files into the store, XtraUpload move those files to the user directory
        /// </summary>
        private void MoveFilesToFolder(FileCompleteContext ctx, gFileItem fileItem)
        {
            string userFolder      = Path.Combine(_uploadOpts.CurrentValue.UploadPath, fileItem.UserId);
            string destFolder      = Path.Combine(userFolder, fileItem.Id);
            string newFileFullPath = Path.Combine(destFolder, fileItem.Id);

            // Create user root directory
            if (!Directory.Exists(userFolder))
            {
                Directory.CreateDirectory(userFolder);
            }
            // Create a new directory inside the user root dir
            if (!Directory.Exists(destFolder))
            {
                Directory.CreateDirectory(destFolder);
            }

            // move all files to the destination folder
            DirectoryInfo directoryInfo = new DirectoryInfo(_uploadOpts.CurrentValue.UploadPath);

            foreach (FileInfo file in directoryInfo.GetFiles(ctx.FileId + "*"))
            {
                // Exemple of file names generated by tus are (...69375.metadata, ...69375.uploadlength ...)
                string[] subNames = file.Name.Split('.');
                string   subName  = subNames.Count() == 2 ? '.' + subNames[1] : string.Empty;
                File.Move(file.FullName, newFileFullPath + subName);
            }

            // Create thumbnails for img file (less than 15mb)
            if (fileItem.MimeType.StartsWith("image") && fileItem.Size < (1024L * 1024L * 15))
            {
                // Todo: move the process of cropping images to a job
                using FileStream smallThumboutStream = new FileStream(newFileFullPath + ".smallthumb.png", FileMode.Create);
                using Image image = Image.Load(File.ReadAllBytes(newFileFullPath), out IImageFormat format);
                if (image.Width >= 800 || image.Height >= 800)
                {
                    int width = 960, height = 640;
                    int aspectRatio = image.Width / image.Height;
                    if (aspectRatio == 0)
                    {
                        height = 960;
                        width  = 640;
                    }
                    using FileStream mediumThumboutStream = new FileStream(newFileFullPath + ".mediumthumb.png", FileMode.Create);
                    Image mediumthumbnail = image.Clone(i => i.Resize(width, height).Crop(new Rectangle(0, 0, width, height)));
                    mediumthumbnail.Save(mediumThumboutStream, format);
                }

                Image smallthumbnail = image.Clone(i => i.Resize(128, 128).Crop(new Rectangle(0, 0, 128, 128)));
                smallthumbnail.Save(smallThumboutStream, format);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Handle the upload completion
        /// </summary>
        protected override async Task OnUploadCompleted(FileCompleteContext ctx)
        {
            try
            {
                gFileItem file = await PersistMetaData(ctx);

                if (file != null)
                {
                    MoveFilesToFolder(ctx, file);

                    // Attach file info to header, because tus send 204 (no response body is allowed)
                    ctx.HttpContext.Response.Headers.Add("upload-data", Helpers.JsonSerialize(file));
                }
            }
            catch (Exception _ex)
            {
                _logger.LogError(_ex.Message);
                throw _ex;
            }
        }