public static Stream GetStream(ExplorerNode node, long start_pos = -1, long end_pos = -1, bool IsUpload = false, object DataEx = null) { if (node.Info.Size < 1) { throw new Exception("Mega GetStream: Filesize <= 0."); } MegaApiClient api = GetClient(node.GetRoot.NodeType.Email); MegaNzNode meganode = new MegaNzNode(node.Info.ID, node.Info.MegaCrypto); if (!IsUpload && start_pos >= 0)//download { long end = end_pos > 0 ? end_pos : node.Info.Size - 1; return(api.Download(meganode, start_pos, end, DataEx)); } else { throw new Exception("Not Support Upload."); } }
public DownloaderResult DownloadFolder(Uri uri) { var client = new MegaApiClient(); client.LoginAnonymous(); Logger.Debug("Successfully log into mega"); try { var nodes = client.GetNodesFromLink(uri) .Where(x => x.Type == NodeType.File && x.Name.EndsWith(".rar")) .ToArray(); if (nodes.Length > 1) { throw new Exception("There's more that 1 rar file on the mega folder"); } else if (nodes.Length <= 0) { throw new Exception("There's no rar in the remote mega folder"); } Logger.Debug("Found a rar file in {0}", uri); var node = nodes[0]; var path = Path.GetTempFileName(); Logger.Debug("Downloading {0} into {1}", node.Name, path); try { using var file = File.Open(path, FileMode.Truncate); { using var downloadStream = client.Download(node); downloadStream.CopyTo(file); } file.Seek(0, 0); using var rar = new ArchiveFile(file); var dir = path + ".extracted"; Logger.Debug("Extracting into {0}", dir); Directory.CreateDirectory(dir); try { rar.Extract(dir); return(new DownloaderResult(dir, node.Name, node.Id, node.Owner, node.ModificationDate ?? node.CreationDate)); } catch { Logger.Warning("Deleting {0} before throwing", dir); Directory.Delete(dir, true); throw; } } finally { Logger.Debug("Removing temporary file {0}", path); File.Delete(path); } } finally { client.Logout(); } }
// TODO: Needs a complete rewrite. Also a append/cache function for resuming incomplete files on the disk. // Should be in separated class with support for events for downloadspeed, is resumable file?, etc. // Should check if file is complete, else it will trigger an WebException -- 416 requested range not satisfiable at every request public async Task <bool> DownloadFileWithResumeAsync(string url, string destinationPath, INode node = null) { long totalBytesReceived = 0; int attemptCount = 0; int bufferSize = settings.BufferSize * 4096; if (File.Exists(destinationPath)) { //temporary method for checking downloaded file if (url.Contains("https://mega.nz/#")) { return(true); } if (url.Contains("https://drive.google.com/")) { return(true); } FileInfo fileInfo = new FileInfo(destinationPath); totalBytesReceived = fileInfo.Length; if (totalBytesReceived >= await CheckDownloadSizeAsync(url)) { return(true); } } if (ct.IsCancellationRequested) { return(false); } FileMode fileMode = totalBytesReceived > 0 ? FileMode.Append : FileMode.Create; using (FileStream fileStream = new FileStream(destinationPath, fileMode, FileAccess.Write, FileShare.Read, bufferSize, true)) { while (true) { attemptCount += 1; if (attemptCount > settings.MaxNumberOfRetries) { return(false); } CancellationTokenRegistration requestRegistration = new CancellationTokenRegistration(); try { if (url.Contains("https://mega.nz/#")) { MegaApiClient client = new MegaApiClient(); client.LoginAnonymous(); Uri link = new Uri(url); Stream stream = node != null?client.Download(node) : client.Download(link); long totalBytesToReceive; totalBytesToReceive = totalBytesReceived + stream.Length; using (Stream throttledStream = GetStreamForDownload(stream)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = await throttledStream.ReadAsync(buffer, 0, buffer.Length, ct)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); totalBytesReceived += bytesRead; } } if (totalBytesReceived >= totalBytesToReceive) { break; } //client.Logout(); } else { HttpWebRequest request = CreateWebReqeust(url); requestRegistration = ct.Register(() => request.Abort()); request.AddRange(totalBytesReceived); long totalBytesToReceive = 0; using (WebResponse response = await request.GetResponseAsync()) { totalBytesToReceive = totalBytesReceived + response.ContentLength; using (Stream responseStream = response.GetResponseStream()) { using (Stream throttledStream = GetStreamForDownload(responseStream)) { byte[] buffer = new byte[4096]; int bytesRead = 0; //Stopwatch sw = Stopwatch.StartNew(); while ((bytesRead = await throttledStream.ReadAsync(buffer, 0, buffer.Length, ct)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); totalBytesReceived += bytesRead; //float currentSpeed = totalBytesReceived / (float)sw.Elapsed.TotalSeconds; //OnProgressChanged(new DownloadProgressChangedEventArgs(totalBytesReceived, // totalBytesToReceive, (long)currentSpeed)); } } } } if (totalBytesReceived >= totalBytesToReceive) { break; } } } catch (IOException ioException) { // file in use long win32ErrorCode = ioException.HResult & 0xFFFF; if ((win32ErrorCode == 0x21) || (win32ErrorCode == 0x20)) { return(false); } // retry (IOException: Received an unexpected EOF or 0 bytes from the transport stream) } catch (WebException webException) { if (webException.Status == WebExceptionStatus.ConnectionClosed) { // retry } else { throw; } } finally { requestRegistration.Dispose(); } } return(true); } }
/// <summary> /// Perform the database download /// </summary> /// <param name="url"></param> /// <param name="path"></param> /// <param name="username"></param> /// <param name="password"></param> private void InternalDownloadDatabase(string url, string path, string username = null, string password = null) { string error = null; var client = new MegaApiClient(); try { INode database = null; if (username is null) { client.LoginAnonymous(); database = client.GetNodesFromLink(new Uri(url)).Where(x => x.Name.EndsWith(".crypt")) .OrderByDescending(x => x.CreationDate) .FirstOrDefault(); } else { client.Login(username, password); database = client.GetNodes().Where(x => x.Name != null && x.Name.EndsWith(".crypt")) .OrderByDescending(x => x.CreationDate) .FirstOrDefault(); } if (database is null) { error = "CantFindFile"; } else { using (var stream = client.Download(database)) { using (var fileStream = File.Create(path)) { stream.CopyTo(fileStream); } } } } catch (ApiException) { error = "ApiError"; } catch (UriFormatException) { error = "InvalidUrl"; } catch (ArgumentException) { error = "InvalidUrl"; } catch (IOException) { error = "CantDownloadFile"; } catch (Exception) { error = "ApiError"; } finally { if (client.IsLoggedIn) { client.Logout(); } } DatabaseDownloadEnded?.Invoke(this, new DatabaseDownloadEndedEventArgs(string.IsNullOrEmpty(error), path, error)); }
private static void Install() { try { var launcherurl = _launcherversion.Linux; var gameurl = _gameversions[_index].Linux; if (Global.IsWindows && Global.Is64bit) { launcherurl = _launcherversion.Windows64; gameurl = _gameversions[_index].Windows64; } else if (Global.IsWindows && !Global.Is64bit) { launcherurl = _launcherversion.Windows32; gameurl = _gameversions[_index].Windows32; } _status = Status.Downloading; _view.Invoke(() => { _view.SetStatus(_status); _view.SetProgress(0); _view.SetStatusText("Preparing..."); }); var client = new MegaApiClient(); client.LoginAnonymous(); if (Assembly.GetEntryAssembly().GetName().Version.ToString() != _launcherversion.Version) { _view.Invoke(() => _view.SetStatusText("Downloading Launcher...")); var temppath = Path.GetTempPath() + Guid.NewGuid().ToString(); using (var fileStream = new FileStream(temppath, FileMode.Create)) using (var downloadStream = new ProgressionStream(client.Download(new Uri(launcherurl)), SetDownloadProgress)) downloadStream.CopyTo(fileStream); _status = Status.Installing; _view.Invoke(() => { _view.SetStatus(_status); _view.SetStatusText("Updating Launcher..."); }); if (Directory.Exists(_updatepath)) { Directory.Delete(_updatepath, true); } Directory.CreateDirectory(_updatepath); ZipFile.ExtractToDirectory(temppath, _updatepath); File.Delete(temppath); if (Global.IsUnix) { Process.Start("mono", Path.Combine(Path.Combine(_basepath, UpdateLocation), "Launcher.exe")); } else { Process.Start(Path.Combine(Path.Combine(_basepath, UpdateLocation), "Launcher.exe")); } Process.GetCurrentProcess().Kill(); } if (!Directory.Exists(Path.Combine(_gamepath, _gameversions[_index].Version))) { _view.Invoke(() => _view.SetStatusText("Downloading Game...")); var temppath = Path.GetTempPath() + Guid.NewGuid().ToString(); using (var fileStream = new FileStream(temppath, FileMode.Create)) using (var downloadStream = new ProgressionStream(client.Download(new Uri(gameurl)), SetDownloadProgress)) downloadStream.CopyTo(fileStream); _status = Status.Installing; _view.Invoke(() => { _view.SetStatus(_status); _view.SetStatusText("Updating Game..."); }); if (Directory.Exists(_gamepath)) { Directory.Delete(_gamepath, true); } Directory.CreateDirectory(_gamepath); ZipFile.ExtractToDirectory(temppath, Path.Combine(_gamepath, _gameversions[_index].Version)); File.Delete(temppath); } } catch (Exception ex) { _view.Invoke(() => _view.ShowError("An error occured while trying to install the game. More Info:" + Environment.NewLine + ex)); SetDownloadProgress(100); } _status = Status.Ready; _view.Invoke(() => { _view.SetStatus(_status); _view.SetStatusText("Ready"); ReloadPlay(); }); }