public override Task<string> GetDownloadLink(Track track, CancellationToken token)
        {
            if (!track.Streamable.GetValueOrDefault(true))
                return Task.FromResult(string.Empty);

            return Task.FromResult($"tracks/{track.Id}/stream?client_id={ClientId}");
        }
        public TrackViewItem(Track track)
        {
            Track = track;

            Text = track.User.Username;
            SubItems.Add(track.Title);
        }
        public static async Task<DownloadInformation> GetDownloadInformation(Track track,
            DownloadRetriever retriever, CancellationToken token)
        {
            var url = await retriever.GetDownloadLink(track, token);  
            if (!string.IsNullOrWhiteSpace(url))
                return new DownloadInformation(retriever.Source, url);

            return new DownloadInformation();
        }      
        private void HandleReportedTracks(Track[] tracks)
        {
            var items = new List<TrackViewItem>();    
            foreach (var track in tracks)
            {
                items.Add(new TrackViewItem(track));

                var path = track.GetPath(tbDownloadFolder.Text, splitArtistsCheckBox.Checked);
                if (File.Exists(path))
                    _totalDownloaded++;     
            }       
            lvTracks.Items.AddRange(items.ToArray<ListViewItem>());   

            InvalidateTotalDownloadsLabel();
        }
        public override async Task<string> GetDownloadLink(Track track, CancellationToken token)
        {
            if (token.IsCancellationRequested)
                return string.Empty;

            var url = track.PermalinkUrl.Replace("http://", "https://");  
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            request.Headers.TryAddWithoutValidation("User-Agent", UserAgent);

            var response = await Client.SendAsync(request, token);
            var content = await response.Content.ReadAsStringAsync();
                                                     
            if (string.IsNullOrWhiteSpace(await GetClientId(content)))
                return string.Empty;

            if (token.IsCancellationRequested)
                return string.Empty;

            url = $"https://api.soundcloud.com/i1/tracks/{track.Id}/streams?client_id={_clientId}";
            content = await Client.GetStringAsync(url);

            var streams = JsonHelper.Deserialize<StreamsResponse>(content);    
            return streams.HTTPMP3123Url;
        }
 public void ReportTracks(Track[] tracks)
 {
     OnReportTracks?.Invoke(tracks);
 }
 public abstract Task<string> GetDownloadLink(Track track, CancellationToken token);
 private void SetID3Tag(string path, Track track)
 {
     try
     {
         var tagger = new UltraID3();
         tagger.Read(path);
         tagger.Title = track.Title;
         tagger.Artist = track.User.Username;
         tagger.Genre = track.Genre;
         tagger.Write();
     }
     catch (Exception ex)
     {
         var entries = new[]
         {
             new LogEntry("Error tagging ", true, false),
             new LogEntry(track.Title, false, false, Config.SoundCloudColor),
             new LogEntry(".", false),
             new LogEntry(ex.Message),
         };
         _logProvider.Log(LogItem.Create(entries));
     }
 }
        private async Task DownloadTrack(Track track, CancellationToken token)
        {
            var path = track.GetPath(tbDownloadFolder.Text, splitArtistsCheckBox.Checked);
            if (File.Exists(path))
            {
                if (cbOverwrite.Checked)
                {            
                    _totalDownloaded--;
                    InvalidateTotalDownloadsLabel();

                    if (!cbOnlyLogErrors.Checked)
                    {
                        var entries = new[]
                        {
                            new LogEntry("Overriding ", true, false),
                            new LogEntry(track.Title, false, false, Config.SoundCloudColor),
                            new LogEntry(".", false),
                        };
                        _logProvider.Log(LogItem.Create(entries));
                    }
                }   
                else                              
                    return;     
            }
                                                                                 
            Invoke(new Action(() => Text = $"{Config.ApplicationName} - \"{track.Title}\""));

            for (var index = 0; index < DownloadRetrieverHelper.Retrievers.Length; index++)
            {
                if (token.IsCancellationRequested)
                    break;

                var retriever = DownloadRetrieverHelper.Retrievers[index];

                if (!cbOnlyLogErrors.Checked)
                {
                    var entries = new[]
                    {
                        new LogEntry("Retrieving download link for ", true, false),
                        new LogEntry(track.Title, false, false, Config.SoundCloudColor),
                        new LogEntry($" from {retriever.Source}.", false),
                    };
                    _logProvider.Log(LogItem.Create(entries));
                }

                try
                {
                    var information = await DownloadRetrieverHelper.GetDownloadInformation(track, retriever, token);
                    if (!information.Success)  
                        throw new Exception("Retrieval of download information failed."); 

                    if (!cbOnlyLogErrors.Checked)
                    {
                        var entries = new[]
                        {
                            new LogEntry("Downloading ", true, false),
                            new LogEntry(track.Title, false, false, Config.SoundCloudColor),
                            new LogEntry($" from {information.Source}.", false),
                        };
                        _logProvider.Log(LogItem.Create(entries));
                    }

                    try
                    {
                        var trackBytes = await _soundCloudProvider.DownloadTrack(information, token);
                        if (trackBytes == null)
                            throw new Exception("Download failed.");

                        File.WriteAllBytes(path, trackBytes);

                        if (cbSetID3Tag.Checked)
                            SetID3Tag(path, track);

                        _totalDownloaded++;
                        InvalidateTotalDownloadsLabel();

                        break;
                    }
                    catch (Exception ex)
                    {
                        var entries = new[]
                        {
                            new LogEntry("Error downloading ", true, false),
                            new LogEntry(track.Title, false, false, Config.SoundCloudColor),
                            new LogEntry(".", false),
                            new LogEntry(ex.Message),
                        };
                        _logProvider.Log(LogItem.Create(entries));
                    }

                    throw new Exception("Retrieval of download information failed.");
                }
                catch (Exception ex)
                {
                    var entries = new[]
                    {
                        new LogEntry("Error retrieving ", true, false),
                        new LogEntry(track.Title, false, false, Config.SoundCloudColor),
                        new LogEntry($" from {retriever.Source}.", false),
                        new LogEntry(ex.Message),
                    };
                    _logProvider.Log(LogItem.Create(entries));

                    if (index != DownloadRetrieverHelper.Retrievers.Length - 1)
                        continue;

                    entries = new[]
                    {
                        new LogEntry("Skipping downloading for ", true, false),
                        new LogEntry(track.Title, false, true, Config.SoundCloudColor),
                        new LogEntry(".", false),
                    }; 
                    _logProvider.Log(LogItem.Create(entries));
                    return;
                }
            }
        }