コード例 #1
0
        public async Task <ImportedSongListContract> ParseAsync(string url, bool parseAll)
        {
            var id = GetId(url);

            var requestUrl = string.Format(playlistsFormat, YoutubeApiKey, id);
            YoutubePlaylistResponse result;

            try {
                result = await JsonRequest.ReadObjectAsync <YoutubePlaylistResponse>(requestUrl);
            } catch (Exception x) {
                log.Warn(x, "Unable to read Youtube playlist");
                throw new UnableToImportException("Unable to read Youtube playlist");
            }

            if (!result.Items.Any())
            {
                log.Info("Youtube playlist not found");
                throw new UnableToImportException(string.Format("Youtube playlist not found: {0}", url));
            }

            var name        = result.Items[0].Snippet.Title;
            var description = result.Items[0].Snippet.Description;
            var created     = (result.Items[0].Snippet.PublishedAt ?? DateTimeOffset.Now).DateTime;

            var songs = await GetSongsById(id, null, 10, parseAll);

            return(new ImportedSongListContract {
                Name = name, Description = description, CreateDate = created, Songs = songs
            });
        }
コード例 #2
0
        private async Task <PartialImportedSongs> GetSongsById(string playlistId, string pageToken, int maxResults, bool parseAll)
        {
            var songs = new List <ImportedSongInListContract>();

            var requestUrl = string.Format(playlistItemsFormat, YoutubeApiKey, playlistId, maxResults, pageToken);

            YoutubePlaylistItemResponse result;

            try {
                result = await JsonRequest.ReadObjectAsync <YoutubePlaylistItemResponse>(requestUrl);
            } catch (Exception x) {
                log.Warn(x, "Unable to read Youtube playlist");
                throw new UnableToImportException("Unable to read Youtube playlist", x);
            }

            foreach (var item in result.Items)
            {
                var song = new ImportedSongInListContract(PVService.Youtube, item.Snippet.ResourceId.VideoId)
                {
                    Name      = item.Snippet.Title,
                    SortIndex = ((int?)item.Snippet.Position ?? 0) + 1,
                    Url       = string.Format("https://www.youtube.com/watch?v={0}", item.Snippet.ResourceId.VideoId)
                };
                songs.Add(song);
            }

            return(new PartialImportedSongs(songs.ToArray(), result.PageInfo.TotalResults ?? 0, result.NextPageToken));
        }
コード例 #3
0
        public async Task <SFSResponseContract> CallApiAsync(string ip)
        {
            if (string.IsNullOrEmpty(ip))
            {
                return(null);
            }

            if (WebHelper.IsLocalhost(ip))
            {
                return(new SFSResponseContract());
            }

            var url = string.Format(apiUrl, ip);
            SFSResultContract result;

            try {
                result = await JsonRequest.ReadObjectAsync <SFSResultContract>(url);
            } catch (WebException x) {
                log.Warn(x, "Unable to get response");
                return(null);
            } catch (JsonSerializationException x) {
                log.Warn(x, "Unable to get response");
                return(null);
            }

            if (!result.Success)
            {
                log.Warn("Request was not successful");
                return(null);
            }

            result.IP.IP = ip;
            return(result.IP);
        }
コード例 #4
0
        public async Task <VideoUrlParseResult> ParseBySoundCloudUrl(string url)
        {
            var apikey = AppConfig.SoundCloudClientId;
            var apiUrl = string.Format("https://api.soundcloud.com/resolve?url=http://soundcloud.com/{0}&client_id={1}", url, apikey);

            SoundCloudResult result;

            bool HasStatusCode(WebException x, HttpStatusCode statusCode) => x.Response != null && ((HttpWebResponse)x.Response).StatusCode == statusCode;

            VideoUrlParseResult ReturnError(Exception x, string additionalInfo = null)
            {
                var msg = string.Format("Unable to load SoundCloud URL '{0}'.{1}", url, additionalInfo != null ? " " + additionalInfo + ".": string.Empty);

                log.Warn(x, msg);
                return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x)));
            }

            try {
                result = await JsonRequest.ReadObjectAsync <SoundCloudResult>(apiUrl, timeoutMs : 10000);
            } catch (WebException x) when(HasStatusCode(x, HttpStatusCode.Forbidden))
            {
                // Forbidden most likely means the artist has prevented API access to their tracks, http://stackoverflow.com/a/36529330
                return(ReturnError(x, "This track cannot be embedded"));
            } catch (WebException x) when(HasStatusCode(x, HttpStatusCode.NotFound))
            {
                return(ReturnError(x, "Not found"));
            } catch (WebException x) {
                return(ReturnError(x));
            } catch (JsonSerializationException x) {
                return(ReturnError(x));
            }

            var trackId = result.Id;
            var title   = result.Title;

            if (trackId == null || title == null)
            {
                return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unable to load SoundCloud URL: Invalid response."));
            }

            var author = result.User.Username;
            var length = result.Duration / 1000;

            var thumbUrl = result.Artwork_url;

            // Substitute song thumbnail with user avatar, if no actual thumbnail is provided. This is what the SoundCloud site does as well.
            if (string.IsNullOrEmpty(thumbUrl))
            {
                thumbUrl = result.User.Avatar_url;
            }

            var uploadDate = result.Created_at;

            var id       = new SoundCloudId(trackId, url);
            var authorId = result.User.Permalink;             // Using permalink because that's the public URL

            return(VideoUrlParseResult.CreateOk(url, PVService.SoundCloud, id.ToString(), VideoTitleParseResult.CreateSuccess(title, author, authorId, thumbUrl, length, uploadDate: uploadDate)));
        }
コード例 #5
0
        public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle)
        {
            var id = GetIdByUrl(url);

            if (string.IsNullOrEmpty(id))
            {
                return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher, "No matcher"));
            }

            var requestUrl = "https://api.bilibili.com/x/web-interface/view?" + (id.StartsWith("BV") ? $"bvid={id}" : $"aid={id}");

            BilibiliResponse response;

            try {
                response = await JsonRequest.ReadObjectAsync <BilibiliResponse>(requestUrl, timeout : TimeSpan.FromSeconds(10), userAgent : "VocaDB/1.0 ([email protected])");
            } catch (Exception x) when(x is HttpRequestException || x is WebException || x is JsonSerializationException || x is IOException)
            {
                log.Warn(x, "Unable to load Bilibili URL {0}", url);
                return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(string.Format("Unable to load Bilibili URL: {0}", x.Message), x)));
            }

            var authorId = response.Data.Owner.Mid.ToString();
            var aid      = response.Data.Aid;
            var bvid     = response.Data.Bvid;
            var cid      = response.Data.Cid;

            if (!getTitle)
            {
                return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, aid.ToString(), VideoTitleParseResult.Empty));
            }

            if (string.IsNullOrEmpty(response.Data.Title))
            {
                return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "No title element"));
            }

            var title   = HtmlEntity.DeEntitize(response.Data.Title);
            var thumb   = response.Data.Pic ?? string.Empty;
            var author  = response.Data.Owner.Name ?? string.Empty;
            var created = response.Data.PubDate;
            var length  = response.Data.Duration;

            var metadata = new PVExtendedMetadata(new BiliMetadata {
                Aid  = aid,
                Bvid = bvid,
                Cid  = cid
            });

            return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, aid.ToString(),
                                                VideoTitleParseResult.CreateSuccess(title, author, authorId, thumb, length: length, uploadDate: created, extendedMetadata: metadata)));
        }
コード例 #6
0
        private async Task <int?> GetLength(string id)
        {
            var requestUrl = string.Format("https://api.bilibili.com/x/player/pagelist?aid={0}", id);

            PlayerResponse result;

            try {
                result = await JsonRequest.ReadObjectAsync <PlayerResponse>(requestUrl);
            } catch (WebException) {
                return(null);
            } catch (JsonSerializationException) {
                return(null);
            }

            return(result?.Data.FirstOrDefault()?.Duration);
        }
コード例 #7
0
 public Task <YoutubeVideoResponse> VideoAsync(string id) => JsonRequest.ReadObjectAsync <YoutubeVideoResponse>(Url(id));