Esempio n. 1
0
 private void downloadFailed(DownloadBeatmapSetRequest d)
 {
     if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
     {
         DownloadState.Value = DownloadStatus.NotDownloaded;
     }
 }
Esempio n. 2
0
        private void attachDownload(DownloadBeatmapSetRequest request)
        {
            if (request.BeatmapSet.OnlineBeatmapSetID != SetInfo.OnlineBeatmapSetID)
            {
                return;
            }

            progressBar.FadeIn(400, Easing.OutQuint);
            progressBar.ResizeHeightTo(4, 400, Easing.OutQuint);

            progressBar.Current.Value = 0;

            request.Failure += e =>
            {
                progressBar.Current.Value = 0;
                progressBar.FadeOut(500);
            };

            request.DownloadProgressed += progress => Schedule(() => progressBar.Current.Value = progress);

            request.Success += data =>
            {
                progressBar.Current.Value = 1;
                progressBar.FillColour    = colours.Yellow;
            };
        }
Esempio n. 3
0
        private void attachDownload(DownloadBeatmapSetRequest request)
        {
            if (attachedRequest != null)
            {
                attachedRequest.Failure            -= onRequestFailure;
                attachedRequest.DownloadProgressed -= onRequestProgress;
                attachedRequest.Success            -= onRequestSuccess;
            }

            attachedRequest = request;

            if (attachedRequest != null)
            {
                if (attachedRequest.Progress == 1)
                {
                    State.Value    = DownloadState.Downloaded;
                    Progress.Value = 1;
                }
                else
                {
                    State.Value    = DownloadState.Downloading;
                    Progress.Value = attachedRequest.Progress;

                    attachedRequest.Failure            += onRequestFailure;
                    attachedRequest.DownloadProgressed += onRequestProgress;
                    attachedRequest.Success            += onRequestSuccess;
                }
            }
            else
            {
                State.Value = DownloadState.NotDownloaded;
            }
        }
Esempio n. 4
0
 private void downloadBegan(DownloadBeatmapSetRequest d)
 {
     if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID)
     {
         DownloadState.Value = DownloadStatus.Downloading;
     }
 }
Esempio n. 5
0
        private void attachDownload(DownloadBeatmapSetRequest request)
        {
            if (request.BeatmapSet.OnlineBeatmapSetID != SetInfo.OnlineBeatmapSetID)
            {
                return;
            }

            progressBar.FadeIn(400, Easing.OutQuint);
            progressBar.ResizeHeightTo(4, 400, Easing.OutQuint);

            progressBar.Current.Value = 0;

            request.Failure += e =>
            {
                progressBar.Current.Value = 0;
                progressBar.FadeOut(500);
                Logger.Error(e, "Failed to get beatmap download information");
            };

            request.DownloadProgressed += progress => progressBar.Current.Value = progress;

            request.Success += data =>
            {
                progressBar.Current.Value = 1;
                progressBar.FadeOut(500);
            };
        }
Esempio n. 6
0
        /// <summary>
        /// Downloads a beatmap.
        /// </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>
        public void Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
        {
            var existing = GetExistingDownload(beatmapSetInfo);

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

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

            ProgressNotification downloadNotification = new ProgressNotification
            {
                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(() =>
                {
                    // 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 OszArchiveReader(stream))
                            Import(archive);

                    downloadNotification.State = ProgressNotificationState.Completed;
                }, TaskCreationOptions.LongRunning);

                currentDownloads.Remove(request);
            };

            request.Failure += data =>
            {
                downloadNotification.State = ProgressNotificationState.Completed;
                Logger.Error(data, "Failed to get beatmap download information");
                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);
        }
Esempio n. 7
0
        /// <summary>
        /// Downloads a beatmap.
        /// </summary>
        /// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
        /// <returns>A new <see cref="DownloadBeatmapSetRequest"/>, or an existing one if a download is already in progress.</returns>
        public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo)
        {
            var existing = GetExistingDownload(beatmapSetInfo);

            if (existing != null)
            {
                return(existing);
            }

            if (api == null)
            {
                return(null);
            }

            ProgressNotification downloadNotification = new ProgressNotification
            {
                Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
            };

            var request = new DownloadBeatmapSetRequest(beatmapSetInfo);

            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(() =>
                {
                    // 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 OszArchiveReader(stream))
                            Import(archive);

                    downloadNotification.State = ProgressNotificationState.Completed;
                }, TaskCreationOptions.LongRunning);

                currentDownloads.Remove(request);
            };

            request.Failure += data =>
            {
                downloadNotification.State = ProgressNotificationState.Completed;
                Logger.Error(data, "Failed to get beatmap download information");
                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);

            return(request);
        }
Esempio 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
            {
                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);
        }
Esempio n. 9
0
        protected void StartDownload()
        {
            if (api == null)
            {
                return;
            }

            // we already have an active download running.
            if (downloadRequest != null)
            {
                content.MoveToX(-5, 50, Easing.OutSine).Then()
                .MoveToX(5, 100, Easing.InOutSine).Then()
                .MoveToX(-5, 100, Easing.InOutSine).Then()
                .MoveToX(0, 50, Easing.InSine).Then();
                return;
            }

            if (!api.LocalUser.Value.IsSupporter)
            {
                notifications.Post(new SimpleNotification
                {
                    Icon = FontAwesome.fa_superpowers,
                    Text = "You gotta be a supporter to download for now 'yo"
                });
                return;
            }

            progressBar.FadeIn(400, Easing.OutQuint);
            progressBar.ResizeHeightTo(4, 400, Easing.OutQuint);

            progressBar.Current.Value = 0;

            ProgressNotification downloadNotification = new ProgressNotification
            {
                Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}",
            };

            downloadRequest          = new DownloadBeatmapSetRequest(SetInfo);
            downloadRequest.Failure += e =>
            {
                progressBar.Current.Value = 0;
                progressBar.FadeOut(500);
                downloadNotification.State = ProgressNotificationState.Completed;
                Logger.Error(e, "Failed to get beatmap download information");

                downloadRequest = null;
            };

            downloadRequest.Progress += (current, total) =>
            {
                float progress = (float)current / total;

                progressBar.Current.Value = progress;

                downloadNotification.State    = ProgressNotificationState.Active;
                downloadNotification.Progress = progress;
            };

            downloadRequest.Success += data =>
            {
                progressBar.Current.Value = 1;
                progressBar.FadeOut(500);

                downloadNotification.State = ProgressNotificationState.Completed;

                using (var stream = new MemoryStream(data))
                    using (var archive = new OszArchiveReader(stream))
                        beatmaps.Import(archive);
            };

            downloadNotification.CancelRequested += () =>
            {
                downloadRequest.Cancel();
                downloadRequest = null;
                return(true);
            };

            notifications.Post(downloadNotification);

            // don't run in the main api queue as this is a long-running task.
            Task.Run(() => downloadRequest.Perform(api));
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        public Tuple <string, Stream> DownloadMap(int beatmapSetId, bool dlVideo = false)
        {
            if (_apiAccess.State == APIState.Offline)
            {
                Logger.Error(new NotSupportedException("API is not Authenticated!"),
                             "API is not Authenticated! check your Login Details!",
                             LoggingTarget.Network);

                throw new UnauthorizedAccessException("API Is not Authorized!");
            }

            if (!_storage.ExistsDirectory("cache"))
            {
                _storage.GetFullPath("cache", true);
            }

            BeatmapSet set;

            if ((set = _factory.Get().BeatmapSet
                       .FirstOrDefault(bmSet => bmSet.SetId == beatmapSetId && !bmSet.Disabled)) == null)
            {
                throw new LegacyScoreParser.BeatmapNotFoundException();
            }

            var cacheStorage = _storage.GetStorageForDirectory("cache");
            var bmFileId     = beatmapSetId.ToString("x8") + (dlVideo ? "" : "_novid");

            CacheBeatmapSet cachedMap;

            if (!cacheStorage.Exists(bmFileId))
            {
                if (!_cleaner.FreeStorage())
                {
                    Logger.Error(new Exception("Cache Storage is full!"),
                                 "Please change the Cleaner Settings!",
                                 LoggingTarget.Database);

                    throw new IOException("Storage Full!");
                }

                try
                {
                    var req = new DownloadBeatmapSetRequest(new BeatmapSetInfo {
                        OnlineBeatmapSetID = beatmapSetId
                    }, !dlVideo);

                    // Video download is not supported, to much traffic. almost no one download videos anyways!

                    var tmpFile = string.Empty;
                    req.Success += c => tmpFile = c;
                    _limiter.Limit();
                    req.Perform(_apiAccess);

                    using (var f = cacheStorage.GetStream(bmFileId, FileAccess.Write))
                        using (var readStream = File.OpenRead(tmpFile))
                            readStream.CopyTo(f);

                    _cleaner.IncreaseSize(new FileInfo(tmpFile).Length);
                    File.Delete(tmpFile);

                    using var db = _cfactory.GetForWrite();

                    if ((cachedMap = db.Context.CacheBeatmapSet.FirstOrDefault(cbm => cbm.SetId == set.SetId)) == null)
                    {
                        db.Context.CacheBeatmapSet.Add(new CacheBeatmapSet
                        {
                            SetId         = set.SetId,
                            DownloadCount = 1,
                            LastDownload  = DateTime.Now
                        });
                    }
                    else
                    {
                        cachedMap.DownloadCount++;
                        cachedMap.LastDownload = DateTime.Now;
                        db.Context.CacheBeatmapSet.Update(cachedMap);
                    }
                } catch (ObjectDisposedException)
                {
                    // Cannot access a closed file.
                    // Beatmap got DMCA'd

                    _search.DeleteBeatmap(beatmapSetId);

                    using (var db = _factory.GetForWrite())
                    {
                        set.Disabled = true;
                        db.Context.BeatmapSet.Update(set);
                    }

                    throw new NotSupportedException("Beatmap got DMCA'd");
                }

                DogStatsd.Increment("beatmap.downloads");

                return(Tuple.Create(
                           $"{set.SetId} {set.Artist} - {set.Title}.osz",
                           cacheStorage.GetStream(bmFileId)));
            }

            using (var db = _cfactory.GetForWrite())
            {
                if ((cachedMap = db.Context.CacheBeatmapSet.FirstOrDefault(cbm => cbm.SetId == set.SetId)) == null)
                {
                    db.Context.CacheBeatmapSet.Add(new CacheBeatmapSet
                    {
                        SetId         = set.SetId,
                        DownloadCount = 1,
                        LastDownload  = DateTime.Now
                    });
                }
                else
                {
                    cachedMap.DownloadCount++;
                    cachedMap.LastDownload = DateTime.Now;
                    db.Context.CacheBeatmapSet.Update(cachedMap);
                }
            }

            DogStatsd.Increment("beatmap.downloads");

            return(Tuple.Create(
                       $"{set.SetId} {set.Artist} - {set.Title}.osz",
                       cacheStorage.GetStream(bmFileId)
                       ));
        }
Esempio n. 12
0
        public DownloadMapResponse DownloadMap(int beatmapSetId, bool dlVideo = false, bool ipfs = false)
        {
            if (_apiProvider.State == APIState.Offline)
            {
                Logger.Error(new NotSupportedException("API is not Authenticated!"),
                             "API is not Authenticated! check your Login Details!",
                             LoggingTarget.Network);

                throw new UnauthorizedAccessException("API Is not Authorized!");
            }

            if (!_storage.ExistsDirectory("cache"))
            {
                _storage.GetFullPath("cache", true);
            }

            BeatmapSet set;

            lock (_dbContextMutes)
            {
                if ((set = _dbContext.BeatmapSet
                           .FirstOrDefault(bmSet => bmSet.SetId == beatmapSetId && !bmSet.Disabled)) == null)
                {
                    throw new LegacyScoreDecoder.BeatmapNotFoundException();
                }
            }

            var cacheStorage = _storage.GetStorageForDirectory("cache");
            var bmFileId     = beatmapSetId.ToString("x8") + (dlVideo ? "" : "_novid");

            CacheBeatmapSet cachedMap;

            if (!cacheStorage.Exists(bmFileId))
            {
                if (!_smartStorage.FreeStorage())
                {
                    Logger.Error(new Exception("Cache Storage is full!"),
                                 "Please change the Cleaner Settings!",
                                 LoggingTarget.Database);

                    throw new IOException("Storage Full!");
                }

                var req = new DownloadBeatmapSetRequest(new BeatmapSetInfo {
                    OnlineBeatmapSetID = beatmapSetId
                },
                                                        !dlVideo);

                var tmpFile = string.Empty;
                req.Success += c => tmpFile = c;
                _limiter.Limit();
                req.Perform(_apiProvider);

                using (var f = cacheStorage.GetStream(bmFileId, FileAccess.Write))
                {
                    using var readStream = File.OpenRead(tmpFile);
                    readStream.CopyTo(f);
                }

                _smartStorage.IncreaseSize(new FileInfo(tmpFile).Length);
                File.Delete(tmpFile);

                using var db = _cacheFactory.GetForWrite();
                if ((cachedMap = db.Context.CacheBeatmapSet.FirstOrDefault(cbm => cbm.SetId == set.SetId)) ==
                    null)
                {
                    db.Context.CacheBeatmapSet.Add(new CacheBeatmapSet
                    {
                        SetId         = set.SetId,
                        DownloadCount = 1,
                        LastDownload  = DateTime.Now
                    });
                }
                else
                {
                    cachedMap.DownloadCount++;
                    cachedMap.LastDownload = DateTime.Now;
                    db.Context.CacheBeatmapSet.Update(cachedMap);
                }

                var cac = _ipfsCache.CacheFile("cache/" + bmFileId);

                return(new DownloadMapResponse {
                    File = $"{set.SetId} {set.Artist} - {set.Title}.osz",
                    FileStream = !ipfs || cac.Result == "" ? cacheStorage.GetStream(bmFileId, FileAccess.Read, FileMode.Open) : null,  // Don't even bother opening a stream.
                    IpfsHash = cac.Result,
                });
            }

            using (var db = _cacheFactory.GetForWrite())
                if ((cachedMap = db.Context.CacheBeatmapSet.FirstOrDefault(cbm => cbm.SetId == set.SetId)) == null)
                {
                    db.Context.CacheBeatmapSet.Add(new CacheBeatmapSet
                    {
                        SetId         = set.SetId,
                        DownloadCount = 1,
                        LastDownload  = DateTime.Now
                    });
                }
                else
                {
                    cachedMap.DownloadCount++;
                    cachedMap.LastDownload = DateTime.Now;
                    db.Context.CacheBeatmapSet.Update(cachedMap);
                }

            var cache = _ipfsCache.CacheFile("cache/" + bmFileId);

            return(new DownloadMapResponse {
                File = $"{set.SetId} {set.Artist} - {set.Title}.osz",
                FileStream = !ipfs || cache.Result == "" ? cacheStorage.GetStream(bmFileId, FileAccess.Read, FileMode.Open) : null,  // Don't even bother opening a stream.
                IpfsHash = cache.Result,
            });
        }