// get all files for given user public HttpResponseMessage GetUserFiles(Guid userId, Guid playlistId) { HttpResponseMessage response; List <CFileInfo> filesInfo = new List <CFileInfo>(); try { List <CFile> files = _fileContext.GetByPlaylistId(playlistId).ToList(); foreach (CFile file in files) { // do not return to user files that are not fully loaded if (file.Hash != null) { CFileInfo fileInfo = file.ToCFileInfo(); filesInfo.Add(fileInfo); } } response = Request.CreateResponse(HttpStatusCode.OK, filesInfo); return(response); } catch (Exception e)// in case program crashes? { HttpContext.Current.Response.StatusCode = (Int32)HttpStatusCode.BadRequest; throw new ContextException(e.Message, e); } }
private void SetUserDetails() { // get user credentials Tuple <string, string> credentials = HelperMethods.NamePasswordFromAuthHeader(Request.Headers.Authorization.Parameter); userName = credentials.Item1; user = _userContext.GetByName(userName); //create full path for the uploaded file userFolder = HttpContext.Current.Server.MapPath($@"~/App_Data/UserFiles/{userName}/"); // get fileInfo from the request header fileInfoHeader = Request.Headers.GetValues("fileInfo"); // get chunk info from the request header chunkSizeHeader = Request.Headers.GetValues("chunkSize"); // get fileInfo from the request header isLastChunkHeader = Request.Headers.GetValues("isLastChunk"); // deserialize file description fileInfo = JsonConvert.DeserializeObject <CFileInfo>(fileInfoHeader.ElementAt(0)); if (String.IsNullOrEmpty(fileInfo.Name)) { fileInfo.Name = $"{userName}_{DateTime.Now}"; } // deserialize chunk size chunkSize = JsonConvert.DeserializeObject <Int32>(chunkSizeHeader.ElementAt(0)); // is last chunk? isLastChunk = JsonConvert.DeserializeObject <Boolean>(isLastChunkHeader.ElementAt(0)); }
public async Task <HttpResponseMessage> DownloadChunkAsync(CFileInfo fileInfo, CUserInfo userInfo, byte[] chunk, bool isLastChunk) { // clear all headers client.DefaultRequestHeaders.Clear(); // set Authorization header client.DefaultRequestHeaders.Authorization = HelperMethods.UserCredentials(userInfo); string fileInfoJson = JsonConvert.SerializeObject(fileInfo); client.DefaultRequestHeaders.Add("fileInfo", fileInfoJson); string chunkSizeJson = JsonConvert.SerializeObject(chunk.Length); client.DefaultRequestHeaders.Add("chunkSize", chunkSizeJson); string isLastChunkJson = JsonConvert.SerializeObject(isLastChunk); client.DefaultRequestHeaders.Add("isLastChunk", isLastChunkJson); HttpContent content = new ByteArrayContent(chunk); content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); HttpResponseMessage response = await client.GetAsync($"api/file/DownloadChunkAsync"); return(response); }
public static List <FileInfo> GetFileInfos() { fileInfos = new List <FileInfo>(); fileInfos.Clear(); GetFirstFile(); CFileInfo cfileInfo = new CFileInfo(); while (NextFind(ref cfileInfo)) { FileInfo fileInfo = new FileInfo { Name = cfileInfo.Name, IsFolder = cfileInfo.IsFolder }; if (fileInfo.IsFolder) { fileInfo.ImagePath = new BitmapImage(new Uri("Image\\folder1.ico", System.UriKind.Relative)); //fileInfo.ImagePath = new BitmapImage(); } else { fileInfo.ImagePath = new BitmapImage(new Uri("Image\\document-icon.png", System.UriKind.Relative)); } fileInfos.Add(fileInfo); } return(fileInfos); }
// Playlist GUIDs are unique for each user public HttpResponseMessage GetFilesFromPlaylist(Guid playlistId) { HttpResponseMessage response; List <CFileInfo> filesInfo = new List <CFileInfo>(); try { List <CFile> filesInPlaylist = _fileContext.FilesFromPlaylist(playlistId).ToList(); foreach (CFile file in filesInPlaylist) { CFileInfo fileInfo = file.ToCFileInfo(); filesInfo.Add(fileInfo); } response = Request.CreateResponse(HttpStatusCode.OK, filesInfo); return(response); } catch (Exception e)// in case program crashes? { HttpContext.Current.Response.StatusCode = (Int32)HttpStatusCode.BadRequest; throw new ContextException(e.Message, e); } }
public async Task <HttpResponseMessage> LikeFileAsync(CFileInfo fileInfo, CUserInfo userInfo) { // clear all headers client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.Authorization = HelperMethods.UserCredentials(userInfo); HttpResponseMessage response = await client.PostAsJsonAsync <CFileInfo>($"api/file/LikeFile", fileInfo); return(response); }
private void ImportStats_Load(object sender, EventArgs e) { try { clParam = new CParamApp(); clFileInfo = new CFileInfo(connect); clRecords = new CRecordsPerson(connect); } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } }
// Request from FileController to Write fileInfo into Dictionary<Guid, List<CPlaylistInfo>> public static bool AddOrUpdate(CFileInfo fileInfo) { try { _rw.EnterWriteLock(); // if no user is present in UserFiles if (!CacheController.UserFiles.Keys.Contains(fileInfo.UserId)) { // insert user and empty List<CPlaylistInfo> CacheController.UserFiles.Add(fileInfo.UserId, new List <CPlaylistInfo>()); } // insert playlists in Dictionary for new user, or for existing if new playlists are present foreach (CPlaylistInfo playlistInfo in fileInfo.playlists) { // Add playlist if it not present in Dictionary CPlaylistInfo existingPlaylist = CacheController.UserFiles[fileInfo.UserId] .Where(p => p.Id.Equals(playlistInfo.Id)).FirstOrDefault(); if (existingPlaylist == null) { CacheController.UserFiles[fileInfo.UserId].Add(playlistInfo); } // get the playlist - at this point it has to exist or be created CPlaylistInfo insertToPlaylist = CacheController.UserFiles[fileInfo.UserId] .Where(p => p.Id.Equals(playlistInfo.Id)).First(); // Add fileInfo if it is not already present in Dictionary CFileInfo existingFileInfo = insertToPlaylist.Files .Where(f => f.Guid.Equals(fileInfo.Guid)).FirstOrDefault(); if (existingFileInfo == null) { // if fileInfo doesn't exist - add new to the Playlist insertToPlaylist.Files.Add(fileInfo); } else { // if fileInfo exist - update its data with new fileInfo existingFileInfo = fileInfo; } } return(true); } catch (Exception ex) { throw new CacheServerException("Error on Cache Service trying to AddOrUpdate file", ex); } finally { _rw.ExitWriteLock(); } }
// check fileLoadIndex for given fileInfo header. public CFileInfo FileDetails(CFileInfo fileInfo) { // get user credentials Tuple <string, string> credentials = HelperMethods.NamePasswordFromAuthHeader(Request.Headers.Authorization.Parameter); userName = credentials.Item1; CUser user = _userContext.GetByName(userName); CFile file = _fileContext.GetByFileName(fileInfo.Name, user.Guid); return(file.ToCFileInfo()); }
public async Task <CFileInfo> FileDetails(CFileInfo fileInfo, CUserInfo userInfo) { // clear all headers client.DefaultRequestHeaders.Clear(); // set Authorization header client.DefaultRequestHeaders.Authorization = HelperMethods.UserCredentials(userInfo); HttpResponseMessage response = await client.PostAsJsonAsync <CFileInfo>($"api/file/FileDetails", fileInfo); CFileInfo fileInfoFromMediaServer = response.Content.ReadAsAsync <CFileInfo>().Result; return(fileInfoFromMediaServer); }
private void FileInfoSgm_Load(object sender, EventArgs e) { try { this.WindowState = FormWindowState.Maximized; clWork = new CFileInfo(connect); gpos = 0; init_data(); } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } }
public async Task <HttpResponseMessage> DownloadFileAsync(CFileInfo fileInfo, CUserInfo userInfo) { // clear all headers client.DefaultRequestHeaders.Clear(); // set Authorization header client.DefaultRequestHeaders.Authorization = HelperMethods.UserCredentials(userInfo); string fileInfoJson = JsonConvert.SerializeObject(fileInfo); client.DefaultRequestHeaders.Add("fileInfo", fileInfoJson); HttpResponseMessage response = await client.GetAsync($"api/file/DownloadAsync?fileId={fileInfo.Guid}"); return(response); }
public static CFileInfo ToCFileInfo(this CFile file) { CFileInfo fileInfo = new CFileInfo(); fileInfo.Guid = file.Guid; fileInfo.Name = file.Name; fileInfo.Size = file.Size; fileInfo.UserId = file.UserId; fileInfo.IsPublic = file.IsPublic; fileInfo.LoadDate = file.LoadDate; fileInfo.Views = file.Views; fileInfo.Likes = file.Likes; fileInfo.Dislikes = file.Dislikes; return(fileInfo); }
private static FileInfo GetFirstFile() { CFileInfo cfileInfo = new CFileInfo(); FileInfo fileInfo = new FileInfo(); if (FirstFind(ref cfileInfo)) { fileInfo.Name = cfileInfo.Name; fileInfo.IsFolder = cfileInfo.IsFolder; if (fileInfo.IsFolder) { fileInfo.ImagePath = new BitmapImage(new Uri("Image\\folder1.ico", System.UriKind.Relative)); } } return(fileInfo); }
// doesn't work internal static async void DownloadFileAsync(CFileInfo fileInfo, CUserInfo userInfo, CancellationToken ct) { try { HttpResponseMessage response = filesWebApi.DownloadFileAsync(fileInfo, userInfo).Result; FileStream fs = new FileStream(fileInfo.Path + fileInfo.Name, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write, UserSettings.ChunkSize, true); using (fs) { await response.Content.CopyToAsync(fs); } Console.WriteLine($"File {fileInfo.Name} has been successfully downloaded!"); } catch (Exception ex) { throw new WebApiException($"File {fileInfo.Name} was not downloaded!", ex); } }
public void DoTest() { String path = System.Configuration.ConfigurationSettings.AppSettings["path"]; String exe = System.Configuration.ConfigurationSettings.AppSettings["exe"]; String outputName = System.Configuration.ConfigurationSettings.AppSettings["output"]; path.TrimEnd(new char[] { '\\' }); path = path + @"\"; // test for file existence String fullName = path + exe; CFileInfo file = new CFileInfo(fullName); Assert.IsTrue(file.Exists, "Unable to find executable : " + fullName); System.Diagnostics.Process proc; // Declare New Process System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(); // Declare New Process Starting Information procInfo.UseShellExecute = false; //If this is false, only .exe's can be run. procInfo.WorkingDirectory = path; //execute notepad from the C: Drive procInfo.FileName = fullName; // Program or Command to Execute. procInfo.Arguments = "-v 0 " + outputName; // no verbose + name of the file to output procInfo.CreateNoWindow = true; procInfo.RedirectStandardError = true; proc = System.Diagnostics.Process.Start(procInfo); proc.WaitForExit(); // Waits for the process to end. // test for errors in the called procedure String procErr = proc.StandardError.ReadToEnd(); Assert.IsTrue((procErr.Length == 0), procErr); CFileInfo outFile = new CFileInfo(path + outputName); // test for outFile existence Assert.IsTrue(outFile.Exists, exe + " was unable to create output file."); StreamReader sr = new StreamReader(outFile.OpenRead()); String strFile = sr.ReadToEnd(); sr.Close(); // if file non-empty then print report Assert.IsTrue((outFile.Length == 0), strFile); }
// Call web api function to upload file from the client internal static void UploadFileAsync(FileInfo fileInfo, bool isPublic, CUserInfo userInfo) { byte[] hash = MD5Generator.MD5Hash(fileInfo.FullName); CFileInfo cFileInfo = new CFileInfo( Guid.Empty, fileInfo.Name, fileInfo.FullName, fileInfo.Length, userInfo.Id, isPublic, hash, DateTime.Now, 0, 0, 0); HttpResponseMessage response = filesWebApi.UploadFileAsync(cFileInfo, userInfo).Result; if (response.IsSuccessStatusCode) { Console.WriteLine($"File {cFileInfo.Name} has been successfully uploaded to MediaServer!"); } else { Console.WriteLine($"File {cFileInfo.Name} couldn't be uploaded to MediaServer! " + $"Response content:{response.ReasonPhrase}"); } }
public static CAsset Create <T>(string name) where T : CAsset, new() { // 1. Create CAsset asset = new T(); string filename = string.Format(".\\asset\\{0}{1}", name, asset.Extension); asset.FileInfo = CFileInfo.SetFileInfo(filename); // 2. Init if (asset.Init() == false) { MessageBox.Show("Asset 초기화 실패"); return(asset); } return(asset); }
public void DoTest() { String path = System.Configuration.ConfigurationSettings.AppSettings["path"]; String exe = System.Configuration.ConfigurationSettings.AppSettings["exe"]; String outputName = System.Configuration.ConfigurationSettings.AppSettings["output"]; path.TrimEnd( new char[]{'\\'} ); path = path + @"\"; // test for file existence String fullName = path + exe; CFileInfo file = new CFileInfo( fullName ); Assert.IsTrue( file.Exists, "Unable to find executable : " + fullName ); System.Diagnostics.Process proc; // Declare New Process System.Diagnostics.ProcessStartInfo procInfo = new System.Diagnostics.ProcessStartInfo(); // Declare New Process Starting Information procInfo.UseShellExecute = false; //If this is false, only .exe's can be run. procInfo.WorkingDirectory = path; //execute notepad from the C: Drive procInfo.FileName = fullName; // Program or Command to Execute. procInfo.Arguments = "-v 0 " + outputName; // no verbose + name of the file to output procInfo.CreateNoWindow = true; procInfo.RedirectStandardError = true; proc = System.Diagnostics.Process.Start( procInfo ); proc.WaitForExit(); // Waits for the process to end. // test for errors in the called procedure String procErr = proc.StandardError.ReadToEnd(); Assert.IsTrue( (procErr.Length == 0), procErr ); CFileInfo outFile = new CFileInfo( path + outputName ); // test for outFile existence Assert.IsTrue( outFile.Exists, exe + " was unable to create output file." ); StreamReader sr = new StreamReader( outFile.OpenRead() ); String strFile = sr.ReadToEnd(); sr.Close(); // if file non-empty then print report Assert.IsTrue( (outFile.Length == 0), strFile ); }
public static bool Delete(CFileInfo fileInfo) { try { _rw.EnterWriteLock(); // if no user is present in UserFiles if (!CacheController.UserFiles.Keys.Contains(fileInfo.UserId)) { return(false); } // find playlists for this user and delete files from them foreach (CPlaylistInfo playlistInfo in fileInfo.playlists) { // existing playlist in Dictionary CPlaylistInfo existingPlaylist = CacheController.UserFiles[fileInfo.UserId] .Where(p => p.Id.Equals(playlistInfo.Id)).FirstOrDefault(); // if Dictionary actually contains playlist mentioned in fileInfo.Playlists if (existingPlaylist != null) { // if file with such Id exists in playlist CFileInfo existingFileInfo = existingPlaylist.Files .Where(f => f.Guid.Equals(fileInfo.Guid)).FirstOrDefault(); if (existingFileInfo != null) { // delete file from playlist existingPlaylist.Files.Remove(existingFileInfo); } } } return(true); } catch (Exception ex) { throw new CacheServerException("Error on Cache Service trying to delete file", ex); } finally { _rw.ExitWriteLock(); } }
public async Task <HttpResponseMessage> UploadFileAsync(CFileInfo fileInfo, CUserInfo userInfo) { // clear all headers client.DefaultRequestHeaders.Clear(); // set Authorization header client.DefaultRequestHeaders.Authorization = HelperMethods.UserCredentials(userInfo); string fileInfoJson = JsonConvert.SerializeObject(fileInfo); client.DefaultRequestHeaders.Add("fileInfo", fileInfoJson); HttpContent content = new StreamContent(File.OpenRead(fileInfo.Path)); content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); HttpResponseMessage response = await client.PostAsync("api/file/UploadAsync", content); return(response); }
// Delete file from Media Server internal static async void DeleteFileAsync(CFileInfo fileInfo, CUserInfo userInfo) { try { HttpResponseMessage response = await filesWebApi.DeleteFileAsync(fileInfo.Guid, userInfo); string msg = ""; if (response.IsSuccessStatusCode) { msg = $"File {fileInfo.Name} has been successfully deleted from Media Server!"; } else { msg = $"Error: File {fileInfo.Name} has not been deleted from Media Server!"; } Console.WriteLine(msg); } catch (Exception ex) { throw new WebApiException($"File {fileInfo.Name} was not deleted!", ex); } }
public HttpResponseMessage DislikeFile(CFileInfo fileInfo) { try { HttpResponseMessage response = new HttpResponseMessage(); CFile file = _fileContext.GetByFileId(fileInfo.Guid); file.Dislikes += 1; if (_fileContext.Update(file) > 0) { Request.CreateResponse(HttpStatusCode.OK, $"File has been Disliked in Media Server."); return(response); } Request.CreateResponse(HttpStatusCode.BadRequest, $"Error: File cannot be updated."); return(response); } catch (ContextException e) { HttpContext.Current.Response.StatusCode = (Int32)HttpStatusCode.BadRequest; throw new ContextException(e.Message, e); } }
// Rename the file in Media Server internal static async void RenameFileAsync(CFileInfo fileInfo, String newName, CUserInfo userInfo) { try { string oldName = fileInfo.Name; HttpResponseMessage response = await filesWebApi.RenameFileAsync(fileInfo.Guid, newName, userInfo); string msg = ""; if (response.IsSuccessStatusCode) { msg = $"File {oldName} has been successfully renamed to {newName}!"; } else { msg = $"Error: File {oldName} has not been renamed to {newName}!"; } Console.WriteLine(msg); } catch (Exception ex) { throw new WebApiException($"File {fileInfo.Name} was not renamed!", ex); } }
public static CAsset Load <T>(CFileInfo fi) where T : CAsset, new() { // 1. Create CAsset asset = new T(); asset.FileInfo = fi; // 2. Load if (CFileSystem.Inst.LoadFile(asset) == false) { MessageBox.Show("Asset 로딩 실패"); return(asset); } // 3. Init if (asset.Init() == false) { MessageBox.Show("Asset 초기화 실패"); return(asset); } return(asset); }
// Called by MediaServer.FileController // If user uploaded/updated(rename, watch, like, dislike) file in Media Server - update cash dictionary. public HttpResponseMessage AddOrUpdateFile(CFileInfo fileInfo) { HttpResponseMessage response; try { if (!UserFiles.Keys.Contains(fileInfo.UserId)) { response = Request.CreateResponse(HttpStatusCode.BadRequest, "User not found in Cache Server"); return(response); } //todo: for all playlists add or update fileINfo foreach (CPlaylistInfo playlistInfo in fileInfo.playlists) { // add playlist to user in Dictionary if absent CPlaylistInfo checkPlaylist = UserFiles[fileInfo.UserId] .Where(p => p.Id.Equals(playlistInfo.Id)).FirstOrDefault(); if (checkPlaylist == null) { UserFiles[fileInfo.UserId].Add(playlistInfo); } // Add userfile to playlist in Cache Server // todo: can we not assign again checkPlaylist, just assign? checkPlaylist = UserFiles[fileInfo.UserId] .Where(p => p.Id.Equals(playlistInfo.Id)).FirstOrDefault(); checkPlaylist.Files.Add(fileInfo); } response = Request.CreateResponse(HttpStatusCode.OK, "File added/updated in Cache Server"); } catch (Exception ex) { response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.ToString()); } return(response); }
public CFile(CFileInfo fileInfo, CUser user, string userFolder) : this( Guid.Empty, fileInfo.Name, userFolder, 0, user.Guid, fileInfo.IsPublic, null, DateTime.Now, 0, 0, 0) { }
static void Main(string[] args) { if (args.Length == 0) { PrintUsage(NO_ARGS); return; } bool bList = false; // Old method, TODO update bool bVerbose = false; bool bUseCsv = false; bool doExtract = false; bool doPack = false; bool doReplace = false; bool _doList = false; // Special case string inFileName = null; string outFileName = null; string workingDir = Directory.GetCurrentDirectory(); string packCompressCodec = null; string packDataAlign = null; string extractWhat = null; string replaceWhat = null; string replaceWith = null; string csvFileName = null; // STEP 1 - PARSE THE ARGUMENTS byte usageHelpFlags = 0x00; bool isUsageSimple = (args[0][0] != '-'); if (!isUsageSimple) // Indicates technical usage vs simple usage; first argument must determine this { for (int i = 0; i < args.Length; i++) { string option = args[i]; if (option[0] == '-') { try { switch (option[1]) { case 'X': doExtract = true; try { extractWhat = args[i + 1]; } catch { extractWhat = null; } break; case 'P': doPack = true; break; case 'R': doReplace = true; try { replaceWhat = args[i + 1]; replaceWith = args[i + 2]; } catch { replaceWhat = null; replaceWith = null; usageHelpFlags |= WRONG_USAGE; } break; case 'L': bList = true; break; case 'i': inFileName = args[i + 1]; break; case 'o': outFileName = args[i + 1]; break; case 'd': workingDir = args[i + 1]; break; case 'v': bVerbose = true; break; // Extra options case '-': switch (option.Substring(2)) { // These are packing options case "codec": packCompressCodec = args[i + 1]; break; case "align": packDataAlign = args[i + 1]; break; // For each packing, extracting, and listing case "csv": bUseCsv = true; try { csvFileName = args[i + 1]; } catch { csvFileName = null; } break; } break; case 'h': usageHelpFlags |= HELP_INFO; break; } } catch { usageHelpFlags |= WRONG_USAGE; break; } } } } else // Simple usage { inFileName = args[0]; try { outFileName = args[1]; } catch { outFileName = null; } } // Set if we only wanted to list the contents _doList = bList && !(doExtract || doPack || doReplace) && !(isUsageSimple); // If we had any reason to stop, now's the time. After this if-statement, it's assumed the user wanted to perform an operation. if ((usageHelpFlags > 0) || (inFileName == null) || (!(doExtract || doPack || doReplace || _doList) && !isUsageSimple)) { PrintUsage(usageHelpFlags); return; } // STEP 2 - VERIFY THAT VALID OPTIONS WERE PASSED (1) input file - Granted the above conditions, inFileName cannot be null at this point if (isUsageSimple || doExtract || doPack || doReplace || _doList) { if (File.Exists(inFileName)) // Applies to drag-n-drop uses { if (isUsageSimple) { doExtract = true; inFileName = (new FileInfo(inFileName)).FullName; } } else if (File.Exists(workingDir + "\\" + inFileName)) { if (isUsageSimple) { doExtract = true; } inFileName = workingDir + "\\" + inFileName; } else if (Directory.Exists(inFileName)) // Applies to drag-n-drop uses { if (isUsageSimple) { doPack = true; inFileName = Path.GetFullPath(inFileName); } } else if (Directory.Exists(workingDir + "\\" + inFileName)) { if (isUsageSimple) { doPack = true; } inFileName = workingDir + "\\" + inFileName; } else { Console.WriteLine("Error: Could not find the specified input file or folder."); return; } } // (2) output path - Preparing output directories if (outFileName != null) { if (!ValidateFilePathString(workingDir, ref outFileName)) { Console.WriteLine("Error: Invalid output path specified. Exiting process."); return; } } // (3) packing options - compression codec, data alignment EnumCompressCodec compressCodec = EnumCompressCodec.CodecDpk; uint dataAlign = 2048; if (doPack) { if (packCompressCodec != null) { if (String.Equals(packCompressCodec, "none", StringComparison.CurrentCultureIgnoreCase)) { compressCodec = EnumCompressCodec.CodecDpk; } else if (String.Equals(packCompressCodec, "layla", StringComparison.CurrentCultureIgnoreCase)) { compressCodec = EnumCompressCodec.CodecLayla; }/* Not implemented, according to CpkMaker * else if (String.Equals(packCompressCodec, "lzma", StringComparison.CurrentCultureIgnoreCase)) * { * compressCodec = EnumCompressCodec.CodecLZMA; * } * else if (String.Equals(packCompressCodec, "relc", StringComparison.CurrentCultureIgnoreCase)) * { * compressCodec = EnumCompressCodec.CodecRELC; * }*/ else { Console.WriteLine("Error: Invalid packing codec specified: \"" + packCompressCodec + "\""); return; } } if (packDataAlign != null) { try { Int32.TryParse(packDataAlign, out int tmp_da); if ((tmp_da > 0) && ((tmp_da & (tmp_da - 1)) == 0)) { dataAlign = (uint)tmp_da; } else { Console.WriteLine("Error: The specified data alignment is not a power of two!"); return; } } catch { Console.WriteLine("Error: A non-number was specified for the data alignment!"); return; } } } // (4) Validate the path for a CSV file if (bUseCsv) { if ((csvFileName == null) || (csvFileName[0] == '-')) { csvFileName = Path.GetFileNameWithoutExtension(inFileName); } if (!(ValidateFilePathString(workingDir, ref csvFileName))) { Console.WriteLine("Error: Unable to prepare a file path for the CSV file!"); return; } if (!String.Equals(Path.GetExtension(csvFileName), ".csv", StringComparison.OrdinalIgnoreCase)) { csvFileName += ".csv"; } } // STEP 3 - NOW HERE'S WHERE THE PROCESS GETS STARTED CpkMaker cpkMaker = new CpkMaker(); CFileData cpkFileData = null; CAsyncFile cManager = new CAsyncFile(); Status status; if (doExtract || doReplace || _doList) { if (!cpkMaker.AnalyzeCpkFile(inFileName)) { Console.WriteLine("Error: AnalyzeCpkFile returned false!"); return; } cpkFileData = cpkMaker.FileData; } if (doExtract) { //Console.WriteLine("DEBUG: doExtract!"); if (outFileName == null) { outFileName = Path.GetDirectoryName(inFileName).Replace('/', '\\') + "\\" + Path.GetFileNameWithoutExtension(inFileName); } if ((extractWhat != null) && (extractWhat[0] != '-')) // If user wanted a specific file { CFileInfo cFileInfo = cpkFileData.GetFileData(extractWhat); if (cFileInfo != null) { outFileName += "\\" + extractWhat.Replace('/', '\\'); try { Directory.CreateDirectory(Path.GetDirectoryName(outFileName)); } catch { } CAsyncFile cpkReader = new CAsyncFile(); cpkReader.ReadOpen(inFileName); cpkReader.WaitForComplete(); CAsyncFile extWriter = new CAsyncFile(); extWriter.WriteOpen(outFileName, false); extWriter.WaitForComplete(); cManager.Copy(cpkReader, extWriter, cFileInfo.Offset, cFileInfo.Filesize, CAsyncFile.CopyMode.ReadDecompress, cFileInfo.Extractsize); cManager.WaitForComplete(); Console.WriteLine("Successfully extracted the file!"); } else { Console.WriteLine("Error: Unable to locate the specified file in the CPK \"" + extractWhat + "\""); return; } } else // Just extract everything { try { Directory.CreateDirectory(outFileName); } catch { } cpkMaker.StartToExtract(outFileName); // Continues at STEP 4 } if (bUseCsv) { if (!ExportCsv(csvFileName, Path.GetFileNameWithoutExtension(outFileName), ref cpkFileData)) { Console.WriteLine("Error: Something went wrong exporting CSV file!"); return; } } } else if (doPack) { //Console.WriteLine("DEBUG: doPack!"); if (bUseCsv) { if (AnalyzeCsv(csvFileName, dataAlign, out CpkMaker csvCpkMaker)) { cpkMaker = csvCpkMaker; } else { Console.WriteLine("Error: AnalyzeCsv() returned false! Invalid CSV entry?"); return; } //if (true) return; // iz debugging PokeSlow } else { cpkMaker.CpkFileMode = CpkMaker.EnumCpkFileMode.ModeFilename; cpkMaker.CompressCodec = compressCodec; cpkMaker.DataAlign = dataAlign; uint i = 0; string[] files = Directory.GetFiles(inFileName, "*", SearchOption.AllDirectories); foreach (string file in files) { if (File.Exists(file)) { string localpath = file.Replace(inFileName, ""); localpath = localpath.Replace('\\', '/'); if (localpath[0] == '/') { localpath = localpath.Substring(1); } //Console.WriteLine("Local path = \"" + localpath + "\""); cpkMaker.AddFile(file, localpath, i++, (((int)compressCodec == 1) ? false : true), "", "", dataAlign); } } } if (outFileName == null) { outFileName = inFileName.Replace('/', '\\') + ".cpk"; } File.Create(outFileName).Close(); cpkMaker.StartToBuild(outFileName); // Continues at STEP 4 } else if (doReplace) { //Console.WriteLine("DEBUG: doReplace!"); CFileInfo cFileInfo = cpkFileData.GetFileData(replaceWhat); if (cFileInfo != null) { if (!(ValidateFilePathString(workingDir, ref replaceWith))) { Console.WriteLine("Error: Unable to locate the specified file to inject."); return; } if (outFileName == null) { outFileName = (workingDir.Replace('/', '\\') + "\\new_" + Path.GetFileName(inFileName)); } if (!(String.Equals(Path.GetExtension(outFileName), ".cpk", StringComparison.OrdinalIgnoreCase))) { outFileName += ".cpk"; } cpkMaker.DeleteFile(replaceWhat); cpkMaker.AddFile(replaceWith, replaceWhat, cFileInfo.FileId, cFileInfo.IsCompressed, cFileInfo.GroupString, cFileInfo.AttributeString, cFileInfo.DataAlign); cpkMaker.FileData.UpdateFileInfoPackingOrder(); Console.WriteLine("Preparing new CPK..."); File.Create(outFileName).Close(); cpkMaker.StartToBuild(outFileName); cpkMaker.WaitForComplete(); CAsyncFile currOldFile = new CAsyncFile(2); currOldFile.ReadOpen(inFileName); currOldFile.WaitForComplete(); CAsyncFile patchedFile = new CAsyncFile(2); patchedFile.WriteOpen(outFileName, true); patchedFile.WaitForComplete(); Console.WriteLine("Patching in files..."); for (int i = 0; i < cpkMaker.FileData.FileInfos.Count; i++) { // I feel like I'd rather just compare CFileInfo.InfoIndex, but I'm a bit paranoid about that... // At least directly comparing the content path is assured without a shadow of a doubt to tell us what we need to know // I want to avoid unnecessary instance invocations of objects and complex conditionals if possible // Please, for the sake of this loop, never invoke CpkMaker.FileData.UpdateFileInfoIndex() //if(String.Equals(cpkFileData.FileInfos[i].ContentFilePath, cFileInfo.ContentFilePath)) { continue; } CFileInfo currNewFileInfo = cpkMaker.FileData.FileInfos[i]; CFileInfo currOldFileInfo = cpkFileData.GetFileData(currNewFileInfo.ContentFilePath); bool wasThisPatched = (currNewFileInfo.InfoIndex == cFileInfo.InfoIndex); if (!wasThisPatched) // Eh, I'll try it. { patchedFile.Position = currNewFileInfo.Offset + currOldFileInfo.DataAlign; //Console.WriteLine("Current position = 0x" + patchedFile.Position.ToString("X8")); currOldFile.ReadAlloc(currOldFileInfo.Offset + currOldFileInfo.DataAlign, currOldFileInfo.Filesize); currOldFile.WaitForComplete(); unsafe { patchedFile.Write(currOldFile.ReadBuffer, currOldFileInfo.Filesize, CAsyncFile.WriteMode.Normal); patchedFile.WaitForComplete(); } currOldFile.ReleaseBuffer(); } if (bVerbose) { Console.WriteLine("[" + currNewFileInfo.InfoIndex.ToString().PadLeft(5) + "] " + (wasThisPatched ? "PATCHED " : " ") + currNewFileInfo.ContentFilePath + " ..."); } //if (true) return; // Used with debugging } Console.WriteLine("Patch complete!"); } else { Console.WriteLine("Error: Unable to locate the specified file in the CPK \"" + replaceWhat + "\""); return; } } else if (_doList) { //Console.WriteLine("DEBUG: doList! - TODO"); if (bVerbose) { cpkMaker.DebugPrintInternalInfo(); } else { Console.WriteLine(cpkMaker.GetCpkInformationString(true, false)); } if (bUseCsv) { if (!ExportCsv(csvFileName, Path.GetFileNameWithoutExtension(inFileName), ref cpkFileData)) { Console.WriteLine("Error: Something went wrong exporting CSV file!"); return; } } } else { Console.WriteLine("Error: Did nothing?"); return; } // STEP 4 - PROGRESS LOOP FOR WHERE APPLICABLE (after I complete the above versions) if (doExtract || doPack) { int last_p = -1; int percent = 0; status = cpkMaker.Execute(); while ((status > Status.Stop) && (percent < 100)) { percent = (int)Math.Floor(cpkMaker.GetProgress()); if (percent > last_p) { Console.CursorLeft = 0; Console.Write(percent.ToString() + "% " + (doExtract ? "extracted" : "packed") + "..."); last_p = percent; } status = cpkMaker.Execute(); } Console.WriteLine(""); Console.WriteLine("Status = " + status.ToString()); } Console.WriteLine("\nProcess finished (hopefully) without issues!"); }
private static extern bool NextFind(ref CFileInfo cfileInfo);
// Call web api function to upload file in small chunks (to overcome 2GB limit on IIS) internal static async void UploadFileInChunksAsync(FileInfo fileInfo, bool isPublic, CUserInfo userInfo, CancellationToken ct) { try { // response from Media SErver string responseMsg = ""; // generate hash of the file // todo: make it multithreaded Console.WriteLine("Calculating file hash..."); byte[] hash = MD5Generator.MD5Hash(fileInfo.FullName); Console.WriteLine($"{fileInfo.Name} hash = {BitConverter.ToString(hash)}"); // set DTO values CFileInfo cFileInfo = new CFileInfo( Guid.Empty, fileInfo.Name, "", fileInfo.Length, userInfo.Id, isPublic, hash, DateTime.Now, 0, 0, 0); // get loadIndex from server (if file was not loaded completely. If new file size==0) CFileInfo fileInfoFromMediaServer = filesWebApi.FileDetails(cFileInfo, userInfo).Result; Int64 loadIndex = fileInfoFromMediaServer.Size; if (loadIndex >= fileInfo.Length) { Console.WriteLine("This file is fully uploaded"); return; } // how much bytes to send to server each time Int32 chunkSize = UserSettings.ChunkSize; FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, chunkSize); using (fs) { // set cursor of the filestream to the loadIndex fs.Seek(loadIndex, SeekOrigin.Begin); HttpResponseMessage response = new HttpResponseMessage(); response.StatusCode = System.Net.HttpStatusCode.OK; Boolean isLastChunk = false; byte[] chunk; // read file to the end and send it to server in chunks while (fs.Position < fs.Length & response.IsSuccessStatusCode) { Int64 remaining = fs.Length - fs.Position; if (remaining <= chunkSize) { isLastChunk = true; chunk = new byte[remaining]; } else { chunk = new byte[chunkSize]; } Int32 readBytes = await fs.ReadAsync(chunk, 0, chunk.Length); // if chunk is uploaded successfully - server returns 'OK' response = filesWebApi.UploadChunkAsync(cFileInfo, userInfo, chunk, isLastChunk).Result; responseMsg = response.Content.ReadAsStringAsync().Result; double percentage = ((double)fs.Position / (double)fs.Length) * 100; Console.Write($"\rUpload progress: {percentage:0.##}%"); } } Console.WriteLine(responseMsg); } catch (Exception ex) { throw new FileUploadException($"Could not upload file {fileInfo.Name} to MediaServer!", ex); } }
// Downloading file from server in chunks internal static async void DownloadFileInChunksAsync(CFileInfo fileInfoMediaServer, CUserInfo userInfo, CancellationToken ct) { try { // how much bytes to send to server each time Int32 chunkSize = UserSettings.ChunkSize; // copy all fields from fileInfoMediaServer CFileInfo fileInfo = new CFileInfo(fileInfoMediaServer); // update path fileInfo.Path = UserSettings.UserFolder; FileStream fs = new FileStream(fileInfo.Path + fileInfo.Name, FileMode.Append, FileAccess.Write, FileShare.Read, chunkSize); using (fs) { HttpResponseMessage response = new HttpResponseMessage(); response.StatusCode = System.Net.HttpStatusCode.OK; byte[] chunk; bool lastChunk = false; // while not all bytes received while (fs.Position < fileInfoMediaServer.Size & response.IsSuccessStatusCode) { Int64 remaining = fileInfoMediaServer.Size - fs.Position; if (remaining <= chunkSize) { chunk = new byte[remaining]; lastChunk = true; } else { chunk = new byte[chunkSize]; } // update fileInfo.Size to match current file stream position fileInfo.Size = fs.Position; // request next chunk of data response = filesWebApi.DownloadChunkAsync(fileInfo, userInfo, chunk, lastChunk).Result; double percentage = 0; if (response.IsSuccessStatusCode) { await response.Content.CopyToAsync(fs); percentage = ((double)fs.Position / (double)fileInfoMediaServer.Size) * 100; Console.Write($"\rDownload progress: {percentage:0.##}%"); } else { Console.Write($"\rDownload chunk failed on: {percentage:0.##}%"); return; } } } Console.WriteLine($"File {fileInfo.Name} is successfully downloaded from Media Server!"); } catch (Exception ex) { throw new FileUploadException($"Could not download file {fileInfoMediaServer.Name} from MediaServer!", ex); } }