Exemplo n.º 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DownloadThread"/> class.
 /// </summary>
 /// <param name="info">
 /// The info.
 /// </param>
 /// <param name="service">
 /// The service.
 /// </param>
 /// <param name="notification">
 /// The notification.
 /// </param>
 internal DownloadThread(DownloadInfo info, DownloaderService service, DownloadNotification notification)
 {
     this.context              = service;
     this.downloadInfo         = info;
     this.downloaderService    = service;
     this.downloadNotification = notification;
     this.UserAgent            = string.Format("APKXDL (Linux; U; Android {0};{1}; {2}/{3}){4}",
                                               Build.VERSION.Release,
                                               System.Threading.Thread.CurrentThread.CurrentCulture.Name,
                                               Build.Device,
                                               Build.Id,
                                               this.downloaderService.PackageName);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DownloadThread"/> class.
 /// </summary>
 /// <param name="info">
 /// The info.
 /// </param>
 /// <param name="service">
 /// The service.
 /// </param>
 /// <param name="notification">
 /// The notification.
 /// </param>
 internal DownloadThread(DownloadInfo info, DownloaderService service, DownloadNotification notification)
 {
     this.context = service;
     this.downloadInfo = info;
     this.downloaderService = service;
     this.downloadNotification = notification;
     this.UserAgent = string.Format("APKXDL (Linux; U; Android {0};{1}; {2}/{3}){4}",
                                    Build.VERSION.Release,
                                    System.Threading.Thread.CurrentThread.CurrentCulture.Name,
                                    Build.Device,
                                    Build.Id,
                                    this.downloaderService.PackageName);
 }
 /// <summary>
 /// The on create.
 /// </summary>
 public override void OnCreate()
 {
     base.OnCreate();
     try
     {
         this.packageInfo = this.PackageManager.GetPackageInfo(this.PackageName, 0);
         string applicationLabel = this.PackageManager.GetApplicationLabel(this.ApplicationInfo);
         this.downloadNotification = new DownloadNotification(this, applicationLabel);
     }
     catch (PackageManager.NameNotFoundException e)
     {
         Log.Error(Tag, e, "Oh oh!");
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Downloads a beatmap.
        /// This will post notifications tracking progress.
        /// </summary>
        /// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
        /// <param name="noVideo">Whether the beatmap should be downloaded without video. Defaults to false.</param>
        /// <returns>Downloading can happen</returns>
        public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
        {
            var existing = GetExistingDownload(beatmapSetInfo);

            if (existing != null || api == null)
            {
                return(false);
            }

            var downloadNotification = new DownloadNotification
            {
                Text = $"Downloading {beatmapSetInfo}",
            };

            var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo);

            request.DownloadProgressed += progress =>
            {
                downloadNotification.State    = ProgressNotificationState.Active;
                downloadNotification.Progress = progress;
            };

            request.Success += filename =>
            {
                Task.Factory.StartNew(() =>
                {
                    // This gets scheduled back to the update thread, but we want the import to run in the background.
                    Import(downloadNotification, filename);
                    currentDownloads.Remove(request);
                }, TaskCreationOptions.LongRunning);
            };

            request.Failure += error =>
            {
                BeatmapDownloadFailed?.Invoke(request);

                if (error is OperationCanceledException)
                {
                    return;
                }

                downloadNotification.State = ProgressNotificationState.Cancelled;
                Logger.Error(error, "Beatmap download failed!");
                currentDownloads.Remove(request);
            };

            downloadNotification.CancelRequested += () =>
            {
                request.Cancel();
                currentDownloads.Remove(request);
                downloadNotification.State = ProgressNotificationState.Cancelled;
                return(true);
            };

            currentDownloads.Add(request);
            PostNotification?.Invoke(downloadNotification);

            // don't run in the main api queue as this is a long-running task.
            Task.Factory.StartNew(() =>
            {
                try
                {
                    request.Perform(api);
                }
                catch
                {
                    // no need to handle here as exceptions will filter down to request.Failure above.
                }
            }, TaskCreationOptions.LongRunning);
            BeatmapDownloadBegan?.Invoke(request);
            return(true);
        }
        /// <summary>
        /// Begin a download for the requested <typeparamref name="TModel"/>.
        /// </summary>
        /// <param name="model">The <typeparamref name="TModel"/> to be downloaded.</param>
        /// <param name="minimiseDownloadSize">Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.</param>
        /// <returns>Whether the download was started.</returns>
        public bool Download(TModel model, bool minimiseDownloadSize = false)
        {
            if (!canDownload(model))
            {
                return(false);
            }

            var request = CreateDownloadRequest(model, minimiseDownloadSize);

            DownloadNotification notification = new DownloadNotification
            {
                Text = $"Downloading {request.Model}",
            };

            request.DownloadProgressed += progress =>
            {
                notification.State    = ProgressNotificationState.Active;
                notification.Progress = progress;
            };

            request.Success += filename =>
            {
                Task.Factory.StartNew(async() =>
                {
                    // This gets scheduled back to the update thread, but we want the import to run in the background.
                    var imported = await Import(notification, filename);

                    // for now a failed import will be marked as a failed download for simplicity.
                    if (!imported.Any())
                    {
                        downloadFailed.Value = new WeakReference <ArchiveDownloadRequest <TModel> >(request);
                    }

                    currentDownloads.Remove(request);
                }, TaskCreationOptions.LongRunning);
            };

            request.Failure += triggerFailure;

            notification.CancelRequested += () =>
            {
                request.Cancel();
                return(true);
            };

            currentDownloads.Add(request);
            PostNotification?.Invoke(notification);

            api.PerformAsync(request);

            downloadBegan.Value = new WeakReference <ArchiveDownloadRequest <TModel> >(request);
            return(true);

            void triggerFailure(Exception error)
            {
                currentDownloads.Remove(request);

                downloadFailed.Value = new WeakReference <ArchiveDownloadRequest <TModel> >(request);

                notification.State = ProgressNotificationState.Cancelled;

                if (!(error is OperationCanceledException))
                {
                    Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Downloads a beatmap.
        /// This will post notifications tracking progress.
        /// </summary>
        /// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
        /// <param name="noVideo">Whether the beatmap should be downloaded without video. Defaults to false.</param>
        /// <returns>Downloading can happen</returns>
        public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
        {
            var existing = GetExistingDownload(beatmapSetInfo);

            if (existing != null || api == null)
            {
                return(false);
            }

            if (!api.LocalUser.Value.IsSupporter)
            {
                PostNotification?.Invoke(new SimpleNotification
                {
                    Icon = FontAwesome.fa_superpowers,
                    Text = "You gotta be an osu!supporter to download for now 'yo"
                });
                return(false);
            }

            var downloadNotification = new DownloadNotification
            {
                CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!",
                Text           = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
            };

            var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo);

            request.DownloadProgressed += progress =>
            {
                downloadNotification.State    = ProgressNotificationState.Active;
                downloadNotification.Progress = progress;
            };

            request.Success += data =>
            {
                downloadNotification.Text = $"Importing {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}";

                Task.Factory.StartNew(() =>
                {
                    BeatmapSetInfo importedBeatmap;

                    // This gets scheduled back to the update thread, but we want the import to run in the background.
                    using (var stream = new MemoryStream(data))
                        using (var archive = new ZipArchiveReader(stream, beatmapSetInfo.ToString()))
                            importedBeatmap = Import(archive);

                    downloadNotification.CompletionClickAction = () =>
                    {
                        PresentCompletedImport(importedBeatmap.Yield());
                        return(true);
                    };
                    downloadNotification.State = ProgressNotificationState.Completed;

                    currentDownloads.Remove(request);
                }, TaskCreationOptions.LongRunning);
            };

            request.Failure += error =>
            {
                BeatmapDownloadFailed?.Invoke(request);

                if (error is OperationCanceledException)
                {
                    return;
                }

                downloadNotification.State = ProgressNotificationState.Cancelled;
                Logger.Error(error, "Beatmap download failed!");
                currentDownloads.Remove(request);
            };

            downloadNotification.CancelRequested += () =>
            {
                request.Cancel();
                currentDownloads.Remove(request);
                downloadNotification.State = ProgressNotificationState.Cancelled;
                return(true);
            };

            currentDownloads.Add(request);
            PostNotification?.Invoke(downloadNotification);

            // don't run in the main api queue as this is a long-running task.
            Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning);
            BeatmapDownloadBegan?.Invoke(request);
            return(true);
        }
 /// <summary>
 /// The on create.
 /// </summary>
 public override void OnCreate()
 {
     base.OnCreate();
     try
     {
         this.packageInfo = this.PackageManager.GetPackageInfo(this.PackageName, 0);
         string applicationLabel = this.PackageManager.GetApplicationLabel(this.ApplicationInfo);
         this.downloadNotification = new DownloadNotification(this, applicationLabel);
     }
     catch (PackageManager.NameNotFoundException e)
     {
         Log.Error(Tag, e, "Oh oh!");
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Downloads a beatmap.
        /// This will post notifications tracking progress.
        /// </summary>
        /// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
        /// <param name="noVideo">Whether the beatmap should be downloaded without video. Defaults to false.</param>
        /// <returns>Downloading can happen</returns>
        public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
        {
            var existing = GetExistingDownload(beatmapSetInfo);

            if (existing != null || api == null)
            {
                return(false);
            }

            var downloadNotification = new DownloadNotification
            {
                CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!",
                Text           = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
            };

            var request = new DownloadBeatmapSetRequest(beatmapSetInfo, noVideo);

            request.DownloadProgressed += progress =>
            {
                downloadNotification.State    = ProgressNotificationState.Active;
                downloadNotification.Progress = progress;
            };

            request.Success += filename =>
            {
                downloadNotification.Text = $"Importing {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}";

                Task.Factory.StartNew(() =>
                {
                    // This gets scheduled back to the update thread, but we want the import to run in the background.
                    var importedBeatmap = Import(filename);

                    downloadNotification.CompletionClickAction = () =>
                    {
                        PresentCompletedImport(importedBeatmap.Yield());
                        return(true);
                    };
                    downloadNotification.State = ProgressNotificationState.Completed;

                    currentDownloads.Remove(request);
                }, TaskCreationOptions.LongRunning);
            };

            request.Failure += error =>
            {
                BeatmapDownloadFailed?.Invoke(request);

                if (error is OperationCanceledException)
                {
                    return;
                }

                downloadNotification.State = ProgressNotificationState.Cancelled;
                Logger.Error(error, "Beatmap download failed!");
                currentDownloads.Remove(request);
            };

            downloadNotification.CancelRequested += () =>
            {
                request.Cancel();
                currentDownloads.Remove(request);
                downloadNotification.State = ProgressNotificationState.Cancelled;
                return(true);
            };

            currentDownloads.Add(request);
            PostNotification?.Invoke(downloadNotification);

            // don't run in the main api queue as this is a long-running task.
            Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning);
            BeatmapDownloadBegan?.Invoke(request);
            return(true);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Begin a download for the requested <see cref="TModel"/>.
        /// </summary>
        /// <param name="model">The <see cref="TModel"/> to be downloaded.</param>
        /// <param name="minimiseDownloadSize">Whether this download should be optimised for slow connections. Generally means extras are not included in the download bundle.</param>
        /// <returns>Whether the download was started.</returns>
        public bool Download(TModel model, bool minimiseDownloadSize = false)
        {
            if (!canDownload(model))
            {
                return(false);
            }

            var request = CreateDownloadRequest(model, minimiseDownloadSize);

            DownloadNotification notification = new DownloadNotification
            {
                Text = $"Downloading {request.Model}",
            };

            request.DownloadProgressed += progress =>
            {
                notification.State    = ProgressNotificationState.Active;
                notification.Progress = progress;
            };

            request.Success += filename =>
            {
                Task.Factory.StartNew(async() =>
                {
                    // This gets scheduled back to the update thread, but we want the import to run in the background.
                    await Import(notification, filename);
                    currentDownloads.Remove(request);
                }, TaskCreationOptions.LongRunning);
            };

            request.Failure += error =>
            {
                DownloadFailed?.Invoke(request);

                if (error is OperationCanceledException)
                {
                    return;
                }

                notification.State = ProgressNotificationState.Cancelled;
                Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
                currentDownloads.Remove(request);
            };

            notification.CancelRequested += () =>
            {
                request.Cancel();
                currentDownloads.Remove(request);
                notification.State = ProgressNotificationState.Cancelled;
                return(true);
            };

            currentDownloads.Add(request);
            PostNotification?.Invoke(notification);

            Task.Factory.StartNew(() => request.Perform(api), TaskCreationOptions.LongRunning);

            DownloadBegan?.Invoke(request);

            return(true);
        }