예제 #1
0
        /// <summary>
        ///     Gets the lyrics for a track asynchronously (cached).
        /// </summary>
        /// <param name="artist">the artist name (e.g. Coldplay)</param>
        /// <param name="title">the title of the track (e.g. "Adventure of a Lifetime")</param>
        /// <param name="cancellationToken">
        ///     a cancellation token that can be used by other objects or threads to receive notice
        ///     of cancellation.
        /// </param>
        /// <returns>
        ///     a task that represents the asynchronous operation. The task result is the track
        ///     found for the query
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     thrown if the specified <paramref name="artist"/> is blank.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     thrown if the specified <paramref name="title"/> is blank.
        /// </exception>
        /// <exception cref="ObjectDisposedException">thrown if the instance is disposed.</exception>
        public async Task <string> GetLyricsAsync(string artist, string title, CancellationToken cancellationToken = default)
        {
            EnsureNotDisposed();

            if (string.IsNullOrWhiteSpace(artist))
            {
                throw new ArgumentException("The specified artist cannot be blank.", nameof(artist));
            }

            if (string.IsNullOrWhiteSpace(title))
            {
                throw new ArgumentException("The specified title cannot be blank.", nameof(title));
            }
            // the cache key
            var key = $"lyrics-{artist}-{title}";

            // check if the item is cached
            if (_cache != null && _cache.TryGetItem <string>(key, out var item))
            {
                return(item);
            }

            var response = await RequestLyricsAsync(artist, title, cancellationToken);

            _cache?.AddItem(key, response, DateTimeOffset.UtcNow + _cacheTime);
            return(response);
        }
        /// <summary>
        ///     Loads the tracks specified by the <paramref name="query"/> asynchronously.
        /// </summary>
        /// <param name="query">the search query</param>
        /// <param name="mode">the track search mode</param>
        /// <param name="noCache">
        ///     a value indicating whether the track should be returned from cache, if it is cached.
        ///     Note this parameter does only take any effect is a cache provider is specified in constructor.
        /// </param>
        /// <param name="cancellationToken">
        ///     a cancellation token that can be used by other objects or threads to receive notice
        ///     of cancellation.
        /// </param>
        /// <returns>
        ///     a task that represents the asynchronous operation. The task result is the request
        ///     response for the specified <paramref name="query"/>.
        /// </returns>
        public async Task <TrackLoadResponsePayload> LoadTracksAsync(string query, SearchMode mode = SearchMode.None,
                                                                     bool noCache = false, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var isUrl = query.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) ||
                        query.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase);

            if (!isUrl)
            {
                if (mode == SearchMode.SoundCloud)
                {
                    query = "scsearch:" + query;
                }
                else if (mode == SearchMode.YouTube)
                {
                    query = "ytsearch:" + query;
                }
            }

            // escape query for passing via URI
            query = Uri.EscapeDataString(query);

            // check if a cache provider is specified in constructor and the track request is cached
            // and caching is wanted (see: "noCache" method parameter)
            if (_cache != null && !noCache && _cache.TryGetItem <TrackLoadResponsePayload>("track-" + query, out var track))
            {
                _logger?.Log(this, string.Format("Loaded track from cache `{0}`.", query), LogLevel.Debug);
                return(track);
            }

            _logger?.Log(this, string.Format("Loading track '{0}'...", query), LogLevel.Debug);

            using (var response = await _httpClient.GetAsync($"loadtracks?identifier={query}", cancellationToken))
            {
                VerifyResponse(response);

                var responseContent = await response.Content.ReadAsStringAsync();

                if (_debugPayloads)
                {
                    _logger?.Log(this, string.Format("Got response for track load: `{0}`: {1}.", query, responseContent), LogLevel.Debug);
                }

                var trackLoad = JsonConvert.DeserializeObject <TrackLoadResponsePayload>(responseContent);

                // cache (if a cache provider is specified)
                _cache?.AddItem("track-" + query, trackLoad, DateTimeOffset.UtcNow + _cacheTime);

                return(trackLoad);
            }
        }