Exemplo n.º 1
0
        public static async Task <(ResultType result, string[] files)> Download(
            IVideoJob job, CancellationToken cancellationToken, string targetFolder, List <DownloadInfo> downloadInfos, int delayPerDownload = 0
            )
        {
            Directory.CreateDirectory(targetFolder);

            List <string> files     = new List <string>(downloadInfos.Count);
            const int     MaxTries  = 5;
            int           triesLeft = MaxTries;

            while (files.Count < downloadInfos.Count)
            {
                if (triesLeft <= 0)
                {
                    job.Status = "Failed to download individual parts after " + MaxTries + " tries, aborting.";
                    return(ResultType.Failure, null);
                }
                files.Clear();
                for (int i = 0; i < downloadInfos.Count; ++i)
                {
                    //for (int i = downloadInfos.Count - 1; i >= 0; --i) {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(ResultType.Cancelled, null);
                    }

                    DownloadInfo downloadInfo = downloadInfos[i];
                    string       outpath      = Path.Combine(targetFolder, downloadInfo.FilesystemId + ".ts");
                    string       outpath_temp = outpath + ".tmp";
                    if (await Util.FileExists(outpath_temp))
                    {
                        await Util.DeleteFile(outpath_temp);
                    }

                    if (outpath.EndsWith("--2d--muted--2e--ts__.ts"))
                    {
                        string alt_outpath = outpath.Substring(0, outpath.Length - "--2d--muted--2e--ts__.ts".Length) + "--2e--ts__.ts";
                        if (await Util.FileExists(alt_outpath))
                        {
                            if (i % 100 == 99)
                            {
                                job.Status = "Already have part " + (i + 1) + "/" + downloadInfos.Count + "...";
                            }
                            files.Add(alt_outpath);
                            continue;
                        }
                    }

                    if (await Util.FileExists(outpath))
                    {
                        if (i % 100 == 99)
                        {
                            job.Status = "Already have part " + (i + 1) + "/" + downloadInfos.Count + "...";
                        }
                        files.Add(outpath);
                        continue;
                    }

                    bool success = false;
                    {
                        System.Net.WebClient client = null;
                        try {
                            if (downloadInfo.Length != null && downloadInfo.Offset != null)
                            {
                                client = new KeepAliveWebClientWithRange(downloadInfo.Offset.Value, downloadInfo.Offset.Value + downloadInfo.Length.Value - 1);
                            }
                            else
                            {
                                client = new KeepAliveWebClient();
                            }

                            job.Status = "Downloading files... (" + (files.Count + 1) + "/" + downloadInfos.Count + ")";
                            byte[] data = await client.DownloadDataTaskAsync(downloadInfo.Url);

                            await job.StallWrite(outpath_temp, data.LongLength, cancellationToken);

                            if (cancellationToken.IsCancellationRequested)
                            {
                                return(ResultType.Cancelled, null);
                            }
                            using (FileStream fs = File.Create(outpath_temp)) {
                                await fs.WriteAsync(data, 0, data.Length);
                            }
                            success = true;
                        } catch (System.Net.WebException ex) {
                            System.Net.HttpWebResponse httpWebResponse = ex.Response as System.Net.HttpWebResponse;
                            if (httpWebResponse != null)
                            {
                                switch (httpWebResponse.StatusCode)
                                {
                                case System.Net.HttpStatusCode.NotFound:
                                    Newtonsoft.Json.Linq.JObject reply = Newtonsoft.Json.Linq.JObject.Parse(new StreamReader(httpWebResponse.GetResponseStream()).ReadToEnd());
                                    string detail = reply["errors"][0]["detail"].ToObject <string>();
                                    if (detail == "No chats for this Video")
                                    {
                                        return(ResultType.Dead, null);
                                    }
                                    break;

                                default:
                                    Console.WriteLine("Server returned unhandled error code: " + httpWebResponse.StatusCode);
                                    break;
                                }
                            }
                            else
                            {
                                Console.WriteLine(ex.ToString());
                            }
                            continue;
                        } finally {
                            if (client != null)
                            {
                                client.Dispose();
                            }
                        }
                    }

                    if (success)
                    {
                        await job.StallWrite(outpath, new FileInfo( outpath_temp ).Length, cancellationToken);

                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(ResultType.Cancelled, null);
                        }
                        File.Move(outpath_temp, outpath);
                        files.Add(outpath);
                    }

                    if (delayPerDownload > 0)
                    {
                        try {
                            await Task.Delay(delayPerDownload, cancellationToken);
                        } catch (TaskCanceledException) {
                            return(ResultType.Cancelled, null);
                        }
                    }
                }

                if (files.Count < downloadInfos.Count)
                {
                    try {
                        await Task.Delay(60000, cancellationToken);
                    } catch (TaskCanceledException) {
                        return(ResultType.Cancelled, null);
                    }
                    --triesLeft;
                }
            }

            return(ResultType.Success, files.ToArray());
        }
Exemplo n.º 2
0
		public bool EnqueueJob( IVideoJob job ) {
			if ( JobExists( job.VideoInfo.Service, job.VideoInfo.VideoId ) ) {
				return false;
			}

			job.StatusUpdater = new StatusUpdate.ObjectListViewStatusUpdate( objectListViewDownloads, job );
			objectListViewDownloads.AddObject( job );
			job.Status = "Waiting...";
			JobQueue.Enqueue( job );

			if ( Util.ShowToastNotifications ) {
				ToastUtil.ShowToast( "Enqueued " + job.HumanReadableJobName + "!" );
			}

			InvokeSaveJobs();

			return true;
		}
Exemplo n.º 3
0
		public async Task RunJob( IVideoJob job = null, bool forceStart = false ) {
			bool runNewJob = false;
			lock ( Lock ) {
				if ( ( forceStart || RunningJobs < MaxRunningJobs ) && ( job != null || JobQueue.TryDequeue( out job ) ) ) {
					// TODO: This almost certainly has odd results if one thread tries to dequeue a job that was force-started from somewhere else!
					++RunningJobs;
					runNewJob = true;
				}
			}

			if ( runNewJob ) {
				try {
					if ( job.JobStatus != VideoJobStatus.Finished ) {
						await job.Run();
						if ( Util.ShowToastNotifications ) {
							ToastUtil.ShowToast( "Downloaded " + job.HumanReadableJobName + "!" );
						}
					}
				} catch ( Exception ex ) {
					job.JobStatus = VideoJobStatus.NotStarted;
					job.Status = "ERROR: " + ex.ToString();
					if ( Util.ShowToastNotifications ) {
						ToastUtil.ShowToast( "Failed to download " + job.HumanReadableJobName + ": " + ex.ToString() );
					}
				}

				InvokeSaveJobs();

				lock ( Lock ) {
					--RunningJobs;
				}

				InvokePowerEvent();

				await RunJob();
			}
		}
Exemplo n.º 4
0
 public bool Equals(IVideoJob other)
 {
     return(other != null && VideoInfo.Equals(other.VideoInfo));
 }