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 }); }
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)); }
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); }
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))); }
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))); }
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); }
public Task <YoutubeVideoResponse> VideoAsync(string id) => JsonRequest.ReadObjectAsync <YoutubeVideoResponse>(Url(id));