/clients/cs/src/youtube/youtubequery.cs

http://google-gdata.googlecode.com/ · C# · 801 lines · 322 code · 69 blank · 410 comment · 41 complexity · 169e7940ed57f44bbdb20f1a9f62f967 MD5 · raw file

  1. /* Copyright (c) 2006 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Xml;
  17. using System.Text;
  18. using System.Globalization;
  19. using System.Diagnostics;
  20. using System.Collections.Generic;
  21. using Google.GData.Client;
  22. namespace Google.GData.YouTube {
  23. /// <summary>
  24. /// A subclass of FeedQuery, to create an YouTube query URI.
  25. /// The YouTube Data API supports the following standard Google Data query parameters.
  26. /// Name Definition
  27. /// alt The alt parameter specifies the format of the feed to be returned.
  28. /// Valid values for this parameter are atom, rss and json. The default
  29. /// value is atom and this document only explains the format of Atom responses.
  30. /// author The author parameter restricts the search to videos uploaded by a
  31. /// particular YouTube user. The Videos uploaded by a specific user
  32. /// section discusses this parameter in more detail.
  33. /// max-results The max-results parameter specifies the maximum number of results
  34. /// that should be included in the result set. This parameter works
  35. /// in conjunction with the start-index parameter to determine which
  36. /// results to return. For example, to request the second set of 10
  37. /// results Đ i.e. results 11-20 Đ set the max-results parameter to 10
  38. /// and the start-index parameter to 11. The default value of this
  39. /// parameter for all Google Data APIs is 25, and the maximum value is 50.
  40. /// However, for displaying lists of videos, we recommend that you
  41. /// set the max-results parameter to 10.
  42. /// start-index The start-index parameter specifies the index of the first matching result
  43. /// that should be included in the result set. This parameter uses a one-based
  44. /// index, meaning the first result is 1, the second result is 2 and so forth.
  45. /// This parameter works in conjunction with the max-results parameter to determine
  46. /// which results to return. For example, to request the second set of 10
  47. /// results Đ i.e. results 11-20 Đ set the start-index parameter to 11
  48. /// and the max-results parameter to 10.
  49. /// Please see the Google Data APIs Protocol Reference for more information about standard Google
  50. /// Data API functionality or about these specific parameters.
  51. /// Custom parameters for the YouTube Data API
  52. /// In addition to the standard Google Data query parameters, the YouTube Data API defines
  53. /// the following API-specific query parameters. These parameters are only available on video
  54. /// and playlist feeds.
  55. /// Name Definition
  56. /// orderby The orderby parameter specifies the value that will be used to sort videos in the
  57. /// search result set. Valid values for this parameter are relevance, published, viewCount
  58. /// and rating. In addition, you can request results that are most relevant to a specific
  59. /// language by setting the parameter value to relevance_lang_languageCode, where
  60. /// languageCode is an ISO 639-1 two-letter language code. (Use the values zh-Hans for
  61. /// simplified Chinese and zh-Hant for traditional Chinese.) In addition, please note that
  62. /// results in other languages will still be returned if they are highly relevant to the
  63. /// search query term.
  64. /// The default value for this parameter is relevance for a search results feed. For a
  65. /// playlist feed, the default ordering is based on the position of each video in the playlist.
  66. /// For a user's playlists or subscriptions feed, the default ordering is arbitrary.
  67. /// client The client parameter is an alphanumeric string that identifies your application. The
  68. /// client parameter is an alternate way of specifying your client ID. You can also use the
  69. /// X-GData-Client request header to specify your client ID. Your application does not need to
  70. /// specify your client ID twice by using both the client parameter and the X-GData-Client
  71. /// request header, but it should provide your client ID using at least one of those two methods.
  72. /// format The format parameter specifies that videos must be available in a particular video format.
  73. /// Your request can specify any of the following formats:
  74. /// Value Video Format
  75. /// 1 RTSP streaming URL for mobile video playback. H.263 video (up to 176x144) and AMR audio.
  76. /// 5 HTTP URL to the embeddable player (SWF) for this video. This format is not available for a
  77. /// video that is not embeddable. Developers commonly add format=5 to their queries to restrict
  78. /// results to videos that can be embedded on their sites.
  79. /// 6 RTSP streaming URL for mobile video playback. MPEG-4 SP video (up to 176x144) and AAC audio
  80. /// lr The lr parameter restricts the search to videos that have a title, description or keywords in a
  81. /// specific language. Valid values for the lr parameter are ISO 639-1 two-letter language codes.
  82. /// You can also use the values zh-Hans for simplified Chinese and zh-Hant for traditional Chinese. This
  83. /// parameter can be used when requesting any video feeds other than standard feeds.
  84. /// restriction The restriction parameter identifies the IP address that should be used to filter videos
  85. /// that can only be played in specific countries. By default, the API filters out videos that cannot
  86. /// be played in the country from which you send API requests. This restriction is based on your
  87. /// client application's IP address.
  88. /// To request videos playable from a specific computer, include the restriction parameter
  89. /// in your request and set the parameter value to the IP address of the computer where the videos
  90. /// will be played Đ e.g. restriction=255.255.255.255.
  91. /// To request videos that are playable in a specific country, include the restriction parameter in your
  92. /// request and set the parameter value to the ISO 3166 two-letter country code of the country where
  93. /// the videos will be played Đ e.g. restriction=DE.
  94. /// time The time parameter, which is only available for the top_rated, top_favorites, most_viewed,
  95. /// most_discussed, most_linked and most_responded standard feeds, restricts the search to videos
  96. /// uploaded within the specified time. Valid values for this parameter are today (1 day),
  97. /// this_week (7 days), this_month (1 month) and all_time. The default value for this parameter is all_time.
  98. /// </summary>
  99. public class YouTubeQuery : FeedQuery {
  100. /// <summary>
  101. /// describing the requested video format
  102. /// </summary>
  103. public enum VideoFormat {
  104. /// <summary>
  105. /// no parameter. Setting the accessLevel to undefined
  106. /// implies the server default
  107. /// </summary>
  108. FormatUndefined = 0,
  109. /// <summary>
  110. /// RTSP streaming URL for mobile video playback. H.263 video (up to 176x144) and AMR audio.
  111. /// </summary>
  112. RTSP = 1,
  113. /// <summary>
  114. /// HTTP URL to the embeddable player
  115. /// </summary>
  116. Embeddable = 5,
  117. /// <summary>
  118. /// SRTSP streaming URL for mobile video playback.
  119. /// </summary>
  120. Mobile = 6,
  121. }
  122. /// <summary>
  123. /// describing the requested video format
  124. /// </summary>
  125. public enum UploadTime {
  126. /// <summary>
  127. /// time undefined, default value for the server
  128. /// </summary>
  129. UploadTimeUndefined,
  130. /// <summary>
  131. /// today (1day)
  132. /// </summary>
  133. Today,
  134. /// <summary>
  135. /// This week (7days)
  136. /// </summary>
  137. ThisWeek,
  138. /// <summary>
  139. /// 1 month
  140. /// </summary>
  141. ThisMonth,
  142. /// <summary>all time</summary>
  143. AllTime
  144. }
  145. /// <summary>
  146. /// describing the possible safe search values
  147. /// <seealso cref="YouTubeQuery.SafeSearch"/>
  148. /// </summary>
  149. public enum SafeSearchValues {
  150. /// <summary>no restriction</summary>
  151. None,
  152. /// <summary>moderate restriction</summary>
  153. Moderate,
  154. /// <summary>strict restriction</summary>
  155. Strict
  156. }
  157. private SafeSearchValues safeSearch;
  158. private List<VideoFormat> formats;
  159. private string videoQuery;
  160. private string orderBy;
  161. private string client;
  162. private string lr;
  163. private string restriction;
  164. private UploadTime uploadTime = UploadTime.UploadTimeUndefined;
  165. private string location;
  166. private string locationRadius;
  167. private string uploader;
  168. /// <summary>
  169. /// the standard feeds URL
  170. /// </summary>
  171. public const string StandardFeeds = "https://gdata.youtube.com/feeds/api/standardfeeds/";
  172. /// <summary>
  173. /// youTube base video URI
  174. /// </summary>
  175. public const string DefaultVideoUri = "https://gdata.youtube.com/feeds/api/videos";
  176. /// <summary>
  177. /// youTube base video URI for batch operations
  178. /// </summary>
  179. public const string BatchVideoUri = "https://gdata.youtube.com/feeds/api/videos/batch";
  180. /// <summary>
  181. /// youTube base mobile video URI
  182. /// </summary>
  183. public const string MobileVideoUri = "https://gdata.youtube.com/feeds/mobile/videos";
  184. /// <summary>
  185. /// youTube base standard top rated video URI
  186. /// </summary>
  187. public const string TopRatedVideo = YouTubeQuery.StandardFeeds + "top_rated";
  188. /// <summary>
  189. /// youTube base standard favorites video URI
  190. /// </summary>
  191. public const string FavoritesVideo = YouTubeQuery.StandardFeeds + "top_favorites";
  192. /// <summary>
  193. /// youTube base standard most viewed video URI
  194. /// </summary>
  195. public const string MostViewedVideo = YouTubeQuery.StandardFeeds + "most_viewed";
  196. /// <summary>
  197. /// youTube base standard most recent video URI
  198. /// </summary>
  199. public const string MostRecentVideo = YouTubeQuery.StandardFeeds + "most_recent";
  200. /// <summary>
  201. /// youTube base standard most popular video URI
  202. /// </summary>
  203. public const string MostPopular = YouTubeQuery.StandardFeeds + "most_popular";
  204. /// <summary>
  205. /// youTube base standard most discussed video URI
  206. /// </summary>
  207. public const string MostDiscussedVideo = YouTubeQuery.StandardFeeds + "most_discussed";
  208. /// <summary>
  209. /// youTube base standard most linked video URI
  210. /// </summary>
  211. public const string MostLinkedVideo = YouTubeQuery.StandardFeeds + "most_linked";
  212. /// <summary>
  213. /// youTube base standard most responded video URI
  214. /// </summary>
  215. public const string MostRespondedVideo = YouTubeQuery.StandardFeeds + "most_responded";
  216. /// <summary>
  217. /// youTube base standard recently featured video URI
  218. /// </summary>
  219. public const string RecentlyFeaturedVideo = YouTubeQuery.StandardFeeds + "recently_featured";
  220. /// <summary>
  221. /// youTube base standard mobile phones video URI
  222. /// </summary>
  223. public const string MobilePhonesVideo = YouTubeQuery.StandardFeeds + "watch_on_mobile";
  224. /// <summary>
  225. /// default users upload account
  226. /// </summary>
  227. public const string DefaultUploads = "https://gdata.youtube.com/feeds/api/users/default/uploads";
  228. /// <summary>
  229. /// base uri for user based feeds
  230. /// </summary>
  231. public const string BaseUserUri = "https://gdata.youtube.com/feeds/api/users/";
  232. /// <summary>
  233. /// base constructor
  234. /// </summary>
  235. public YouTubeQuery()
  236. : base() {
  237. this.CategoryQueriesAsParameter = true;
  238. this.SafeSearch = SafeSearchValues.Moderate;
  239. }
  240. /// <summary>
  241. /// base constructor, with initial queryUri
  242. /// </summary>
  243. /// <param name="queryUri">the query to use</param>
  244. public YouTubeQuery(string queryUri)
  245. : base(queryUri) {
  246. this.CategoryQueriesAsParameter = true;
  247. this.SafeSearch = SafeSearchValues.Moderate;
  248. }
  249. /// <summary>
  250. /// format The format parameter specifies that videos must be available in a particular video format.
  251. /// Your request can specify any of the following formats:
  252. /// Value Video Format
  253. /// 1 RTSP streaming URL for mobile video playback. H.263 video (up to 176x144) and AMR audio.
  254. /// 5 HTTP URL to the embeddable player (SWF) for this video. This format is not available for a
  255. /// video that is not embeddable. Developers commonly add format=5 to their queries to restrict
  256. /// results to videos that can be embedded on their sites.
  257. /// 6 RTSP streaming URL for mobile video playback. MPEG-4 SP video (up to 176x144) and AAC audio
  258. /// </summary>
  259. /// <returns> the list of formats</returns>
  260. public List<VideoFormat> Formats {
  261. get {
  262. if (this.formats == null) {
  263. this.formats = new List<VideoFormat>();
  264. }
  265. return this.formats;
  266. }
  267. }
  268. /// <summary>accessor method public UploadTime Time</summary>
  269. /// <returns> </returns>
  270. public UploadTime Time {
  271. get { return this.uploadTime; }
  272. set { this.uploadTime = value; }
  273. }
  274. /// <summary>
  275. /// The orderby parameter, which is only supported for video feeds,
  276. /// specifies the value that will be used to sort videos in the search
  277. /// result set. Valid values for this parameter are relevance,
  278. /// published, viewCount and rating. In addition, you can request
  279. /// results that are most relevant to a specific language by
  280. /// setting the parameter value to relevance_lang_languageCode,
  281. /// where languageCode is an ISO 639-1 two-letter
  282. /// language code. (Use the values zh-Hans for simplified Chinese
  283. /// and zh-Hant for traditional Chinese.) In addition,
  284. /// please note that results in other languages will still be
  285. /// returned if they are highly relevant to the search query term.
  286. /// The default value for this parameter is relevance
  287. /// for a search results feed.
  288. /// accessor method public string OrderBy</summary>
  289. /// <returns> </returns>
  290. public string OrderBy {
  291. get { return this.orderBy; }
  292. set { this.orderBy = value; }
  293. }
  294. /// <summary>
  295. /// The client parameter is an alphanumeric string that identifies your
  296. /// application. The client parameter is an alternate way of specifying
  297. /// your client ID. You can also use the X-GData-Client request header to
  298. /// specify your client ID. Your application does not need to
  299. /// specify your client ID twice by using both the client parameter and
  300. /// the X-GData-Client request header, but it should provide your
  301. /// client ID using at least one of those two methods.
  302. /// Note that you should set this normally on the YouTubeService object,
  303. /// this property is only included for completeness
  304. /// </summary>
  305. /// <returns> </returns>
  306. public string Client {
  307. get { return this.client; }
  308. set { this.client = value; }
  309. }
  310. /// <summary>
  311. /// The lr parameter restricts the search to videos that have a title,
  312. /// description or keywords in a specific language. Valid values for
  313. /// the lr parameter are ISO 639-1 two-letter language codes. You can
  314. /// also use the values zh-Hans for simplified Chinese and zh-Hant
  315. /// for traditional Chinese. This parameter can be used when requesting
  316. /// any video feeds other than standard feeds.
  317. /// </summary>
  318. public string LR {
  319. get { return this.lr; }
  320. set { this.lr = value; }
  321. }
  322. /// <summary>
  323. /// <para>
  324. /// The safeSearch parameter indicates whether the search results should include
  325. /// restricted content as well as standard content. YouTube will determine whether
  326. /// content is restricted based on the user's IP address or location, which you specify
  327. /// in your API request using the restriction parameter. If you do request restricted
  328. /// content, then feed entries for videos that contain restricted content will
  329. /// contain the &gt;media:rating&lt; element.
  330. /// </para>
  331. /// The following values are valid for this parameter:
  332. /// </para>
  333. /// <list>
  334. /// <listheader><term>Value</term><description>Description</description></listheader>
  335. /// <item><term>none</term><description>YouTube will not perform any filtering on the search result set.</description></iterm>
  336. /// <item><term>moderate</term><description>YouTube should try to exclude the most explicit content from the search result set. Based on their
  337. /// content, search results could be removed from search results or demoted in search results.</description></iterm>
  338. /// <item><term>strict</term><description>YouTube should try to exclude all restricted content from the search result set. Based on their content, search
  339. /// results could be removed from search results or demoted in search results</description></iterm>
  340. ///<para>The default value for this parameter is moderate.</para>
  341. ///<para>SafeSearch filtering for the YouTube Data API is designed to function similarly to SafeSearch Filtering for Google WebSearch results.
  342. /// Please note that YouTube makes every effort to remove restricted content from search results in accordance with the SafeSearch setting that you specify.
  343. /// However, filters may not be 100% accurate and restricted videos may occasionally appear in search results even if you have specified strict SafeSearch filtering.
  344. /// If this happens, please flag the video by filing a complaint, which will help us to better identify restricted content.</para>
  345. ///<para>Note: The safeSearch parameter was introduced in version 2.0 of the YouTube Data API and replaced the racy parameter, which was used in version 1.0.</para>
  346. /// </summary>
  347. public SafeSearchValues SafeSearch {
  348. get { return this.safeSearch; }
  349. set { this.safeSearch = value; }
  350. }
  351. /// <summary>
  352. /// The location parameter restricts the search to videos that have a geographical location specified in their metadata. The parameter can be used in either of the following contexts:
  353. /// <para>The parameter value can specify geographic coordinates (latitude,longitude) that identify a particular location. In this context, the location parameter
  354. /// operates in conjunction with the location-radius parameter to define a geographic area. The API response will then contain videos that are associated with a
  355. /// geographical location within that area.</para>
  356. /// <para>Note that when a user uploads a video to YouTube, the user can associate a location with the video by either specifying geographic coordinates (-122.08427,37.42307)
  357. /// or by providing a descriptive address (Munich, Germany). As such, some videos may be associated with a location within the area specified in a search query
  358. /// even though those videos are not associated with specific coordinates that can be plotted on a map.</para>
  359. /// <para>To exclude videos from the API response if those videos are associated with a descriptive address but not with specific geographic coordinates, append
  360. /// an exclamation point ("!") to the end of the parameter value. This practice effectively ensures that all videos in the API response can be plotted on a map.</para>
  361. /// <para>The following examples show sample uses of this parameter:</para>
  362. /// <para>location=37.42307,-122.08427&location-radius=100km</para>
  363. /// <para>location=37.42307,-122.08427!&location-radius=100km</para>
  364. /// <para>location=37.42307,-122.08427&location-radius=100km</para>
  365. /// <para>In an API response, feed entries that are associated with specific coordinates will contain the georss:where tag and may also contain the yt:location tag.
  366. /// Feed entries that are associated with a descriptive address but not with specific geographic cooordinates specify the address using the yt:location tag.
  367. /// <para>The parameter value can be a single exclamation point. In this context, the parameter does not require a value and its presence serves to
  368. /// restrict the search results to videos that have a geographical location, but it does not enable you to find videos with a specific geographical location.
  369. /// This parameter can be used with all video feeds. A video that has a geographical location will have a georss:where tag in its metadata.<para>
  370. /// </summary>
  371. public string Location {
  372. get {
  373. return this.location;
  374. }
  375. set {
  376. this.location = value;
  377. }
  378. }
  379. /// <summary>
  380. /// The location-radius parameter, in conjunction with the location parameter, defines a geographic area. If the geographic coordinates associated with a video fall
  381. /// within that area, then the video may be included in search results.
  382. /// <para>The location-radius parameter value must be a floating point number followed by a measurement unit. Valid measurement units are m, km, ft and mi.
  383. /// For example, valid parameter values include "1500m", "5km", "10000ft" and "0.75mi". The API will return an error if the radius is greater than 1000 kilometers.</para>
  384. /// <seealso cref="YouTubeQuery.Location"/>
  385. /// </summary>
  386. /// <returns></returns>
  387. public string LocationRadius {
  388. get {
  389. return this.locationRadius;
  390. }
  391. set {
  392. this.locationRadius = value;
  393. }
  394. }
  395. /// <summary>
  396. /// The restriction parameter identifies the IP address that should be
  397. /// used to filter videos that can only be played in specific countries.
  398. /// We recommend that you always use this parameter to specify the end
  399. /// user's IP address. (By default, the API filters out videos that
  400. /// cannot be played in the country from which you send API requests.
  401. /// This restriction is based on your client application's IP address.)
  402. /// To request videos playable from a specific computer, include the
  403. /// restriction parameter in your request and set the parameter value
  404. /// to the IP address of the computer where the videos will be
  405. /// played Đ e.g. restriction=255.255.255.255.
  406. /// To request videos that are playable in a specific country,
  407. /// include the restriction parameter in your request and set
  408. /// the parameter value to the ISO 3166 two-letter country code
  409. /// of the country where the videos will be played
  410. /// Đ e.g. restriction=DE.
  411. /// </summary>
  412. /// <returns> </returns>
  413. public string Restriction {
  414. get { return this.restriction; }
  415. set { this.restriction = value; }
  416. }
  417. /// <summary>
  418. /// The uploader parameter, which is only supported for search requests, lets you restrict a query to YouTube
  419. /// partner videos. A YouTube partner is a person or organization that has been accepted into and participates
  420. /// in the YouTube Partner Program.
  421. /// <para>In an API response, a feed entry contains a partner video if the entry contains a media:credit tag for
  422. /// which the value of the yt:type attribute is partner.</para>
  423. /// </summary>
  424. /// <returns></returns>
  425. public string Uploader {
  426. get {
  427. return this.uploader;
  428. }
  429. set {
  430. this.uploader = value;
  431. }
  432. }
  433. /// <summary>
  434. /// convenience method to create an URI based on a userID
  435. /// for the subscriptions
  436. /// </summary>
  437. /// <param name="userID"></param>
  438. /// <returns>string</returns>
  439. public static string CreateSubscriptionUri(string userID) {
  440. return CreateCustomUri(userID, "subscriptions");
  441. }
  442. /// <summary>
  443. /// convenience method to create an URI based on a userID
  444. /// for the playlists of an user
  445. /// </summary>
  446. /// <param name="userID"></param>
  447. /// <returns>string</returns>
  448. public static string CreatePlaylistsUri(string userID) {
  449. return CreateCustomUri(userID, "playlists");
  450. }
  451. /// <summary>
  452. /// convenience method to create an URI based on a userID
  453. /// for the favorites of an user
  454. /// </summary>
  455. /// <param name="userID"></param>
  456. /// <returns>string</returns>
  457. public static string CreateFavoritesUri(string userID) {
  458. return CreateCustomUri(userID, "favorites");
  459. }
  460. /// <summary>
  461. /// convenience method to create an URI based on a userID
  462. /// for the messages of an user
  463. /// </summary>
  464. /// <param name="userID"></param>
  465. /// <returns>string</returns>
  466. public static string CreateMessagesUri(string userID) {
  467. return CreateCustomUri(userID, "inbox");
  468. }
  469. /// <summary>
  470. /// convenience method to create an URI based on a userID
  471. /// for the contacts of an user
  472. /// </summary>
  473. /// <param name="userID"></param>
  474. /// <returns>string</returns>
  475. public static string CreateContactsUri(string userID) {
  476. return CreateCustomUri(userID, "contacts");
  477. }
  478. /// <summary>
  479. /// convenience method to create an URI based on a userID
  480. /// for the shows of an user
  481. /// </summary>
  482. /// <param name="userID"></param>
  483. /// <returns>string</returns>
  484. public static string CreateShowsUri(string userID) {
  485. return CreateCustomUri(userID, "shows");
  486. }
  487. /// <summary>
  488. /// convenience method to create an URI based on a userID
  489. /// for the uploaded videos of an user
  490. /// </summary>
  491. /// <param name="userID"></param>
  492. /// <returns>string</returns>
  493. public static string CreateUserUri(string userID) {
  494. return CreateCustomUri(userID, "uploads");
  495. }
  496. /// <summary>
  497. /// assuming you have a video ID, returns the watch uri as a string
  498. /// </summary>
  499. /// <param name="videoID"></param>
  500. /// <returns></returns>
  501. public static string CreateVideoWatchUri(string videoID) {
  502. return "https://www.youtube.com/watch?v=" + Google.GData.Client.Utilities.UriEncodeUnsafe(videoID);
  503. }
  504. /// <summary>
  505. /// assuming you have a video ID, returns the video feed uri as a string
  506. /// </summary>
  507. /// <param name="videoID"></param>
  508. /// <returns></returns>
  509. public static string CreateVideoUri(string videoID) {
  510. return DefaultVideoUri + "/" + Google.GData.Client.Utilities.UriEncodeUnsafe(videoID);
  511. }
  512. // helper method for the above publics
  513. private static string CreateCustomUri(string userID, string path) {
  514. if (String.IsNullOrEmpty(userID)) {
  515. return YouTubeQuery.BaseUserUri + "default/" + path;
  516. }
  517. return YouTubeQuery.BaseUserUri + userID + "/" + path;
  518. }
  519. /// <summary>
  520. /// retrieves the youtubecategories collection from the default
  521. /// location at http://gdata.youtube.com/schemas/2007/categories.cat
  522. /// </summary>
  523. /// <returns></returns>
  524. public static AtomCategoryCollection GetYouTubeCategories() {
  525. return GetCategories(new Uri("http://gdata.youtube.com/schemas/2007/categories.cat"), new YouTubeCategoryCollection());
  526. }
  527. /// <summary>
  528. /// retrieves a category collection from the given URL
  529. /// The owner should be a new Collection object, like:
  530. /// <code>
  531. /// GetCategories(new Uri("http://gdata.youtube.com/schemas/2007/categories.cat"),
  532. /// new YouTubeCategoryCollection())
  533. /// </code>
  534. /// </summary>
  535. /// <returns></returns>
  536. public static AtomCategoryCollection GetCategories(Uri uri, AtomBase owner) {
  537. // first order is to get the document into an xml dom
  538. XmlTextReader textReader = new XmlTextReader(uri.AbsoluteUri);
  539. AtomFeedParser parser = new AtomFeedParser();
  540. AtomCategoryCollection collection = parser.ParseCategories(textReader, owner);
  541. return collection;
  542. }
  543. /// <summary>protected void ParseUri</summary>
  544. /// <param name="targetUri">takes an incoming Uri string and parses all the properties out of it</param>
  545. /// <returns>throws a query exception when it finds something wrong with the input, otherwise returns a baseuri</returns>
  546. protected override Uri ParseUri(Uri targetUri) {
  547. base.ParseUri(targetUri);
  548. if (targetUri == null) {
  549. return this.Uri;
  550. }
  551. char[] deli = { '?', '&' };
  552. string source = HttpUtility.UrlDecode(targetUri.Query);
  553. TokenCollection tokens = new TokenCollection(source, deli);
  554. foreach (string token in tokens) {
  555. if (token.Length == 0) {
  556. continue;
  557. }
  558. char[] otherDeli = { '=' };
  559. string[] parameters = token.Split(otherDeli, 2);
  560. switch (parameters[0]) {
  561. case "format":
  562. if (parameters[1] != null) {
  563. string[] formats = parameters[1].Split(new char[] { ',' });
  564. foreach (string f in formats) {
  565. this.Formats.Add((VideoFormat)Enum.Parse(typeof(VideoFormat), f));
  566. }
  567. }
  568. break;
  569. case "orderby":
  570. this.OrderBy = parameters[1];
  571. break;
  572. case "client":
  573. this.Client = parameters[1];
  574. break;
  575. case "lr":
  576. this.LR = parameters[1];
  577. break;
  578. case "location":
  579. this.Location = parameters[1];
  580. break;
  581. case "location-radius":
  582. this.LocationRadius = parameters[1];
  583. break;
  584. case "uploader":
  585. this.Uploader = parameters[1];
  586. break;
  587. case "safeSearch":
  588. if ("none" == parameters[1]) {
  589. this.SafeSearch = SafeSearchValues.None;
  590. } else if ("moderate" == parameters[1]) {
  591. this.SafeSearch = SafeSearchValues.Moderate;
  592. } else if ("strict" == parameters[1]) {
  593. this.SafeSearch = SafeSearchValues.Strict;
  594. }
  595. break;
  596. case "restriction":
  597. this.Restriction = parameters[1];
  598. break;
  599. case "time":
  600. if ("all_time" == parameters[1]) {
  601. this.Time = UploadTime.AllTime;
  602. } else if ("this_month" == parameters[1]) {
  603. this.Time = UploadTime.ThisMonth;
  604. } else if ("today" == parameters[1]) {
  605. this.Time = UploadTime.Today;
  606. } else if ("this_week" == parameters[1]) {
  607. this.Time = UploadTime.ThisWeek;
  608. } else {
  609. this.Time = UploadTime.UploadTimeUndefined;
  610. }
  611. break;
  612. }
  613. }
  614. return this.Uri;
  615. }
  616. /// <summary>Creates the partial URI query string based on all
  617. /// set properties.</summary>
  618. /// <returns> string => the query part of the URI </returns>
  619. protected override string CalculateQuery(string basePath) {
  620. string path = base.CalculateQuery(basePath);
  621. StringBuilder newPath = new StringBuilder(path, 2048);
  622. char paramInsertion = InsertionParameter(path);
  623. if (this.formats != null) {
  624. string res = "";
  625. foreach (VideoFormat v in this.formats) {
  626. if (res.Length > 0) {
  627. res += ",";
  628. }
  629. res += (int)v;
  630. }
  631. if (res.Length > 0) {
  632. newPath.Append(paramInsertion);
  633. newPath.AppendFormat(CultureInfo.InvariantCulture, "format={0}", Utilities.UriEncodeReserved(res));
  634. paramInsertion = '&';
  635. }
  636. }
  637. if (this.Time != UploadTime.UploadTimeUndefined) {
  638. string res = "";
  639. switch (this.Time) {
  640. case UploadTime.AllTime:
  641. res = "all_time";
  642. break;
  643. case UploadTime.ThisMonth:
  644. res = "this_month";
  645. break;
  646. case UploadTime.ThisWeek:
  647. res = "this_week";
  648. break;
  649. case UploadTime.Today:
  650. res = "today";
  651. break;
  652. }
  653. paramInsertion = AppendQueryPart(res, "time", paramInsertion, newPath);
  654. }
  655. if (this.SafeSearch != SafeSearchValues.Moderate) {
  656. string res = "";
  657. switch (this.SafeSearch) {
  658. case SafeSearchValues.None:
  659. res = "none";
  660. break;
  661. case SafeSearchValues.Strict:
  662. res = "strict";
  663. break;
  664. }
  665. paramInsertion = AppendQueryPart(res, "safeSearch", paramInsertion, newPath);
  666. }
  667. paramInsertion = AppendQueryPart(this.Location, "location", paramInsertion, newPath);
  668. paramInsertion = AppendQueryPart(this.LocationRadius, "location-radius", paramInsertion, newPath);
  669. paramInsertion = AppendQueryPart(this.Uploader, "uploader", paramInsertion, newPath);
  670. paramInsertion = AppendQueryPart(this.OrderBy, "orderby", paramInsertion, newPath);
  671. paramInsertion = AppendQueryPart(this.Client, "client", paramInsertion, newPath);
  672. paramInsertion = AppendQueryPart(this.LR, "lr", paramInsertion, newPath);
  673. paramInsertion = AppendQueryPart(this.Restriction, "restriction", paramInsertion, newPath);
  674. return newPath.ToString();
  675. }
  676. }
  677. /// <summary>
  678. /// A subclass of FeedQuery, to create an Activities Query for YouTube.
  679. /// A user activity feed contains information about actions that an authenticated user's
  680. /// friends have recently taken on the YouTube site.
  681. public class ActivitiesQuery : FeedQuery {
  682. /// <summary>
  683. /// youTube events feed for friends activities
  684. /// </summary>
  685. public const string ActivityFeedUri = "https://gdata.youtube.com/feeds/api/users/default/friendsactivity";
  686. /// <summary>
  687. /// base constructor
  688. /// </summary>
  689. public ActivitiesQuery()
  690. : base(ActivitiesQuery.ActivityFeedUri) {
  691. }
  692. }
  693. /// <summary>
  694. /// A subclass of FeedQuery, to create an Activities Query for YouTube.
  695. /// A user activity feed contains information about actions that an authenticated user's
  696. /// friends have recently taken on the YouTube site.
  697. public class UserActivitiesQuery : FeedQuery {
  698. /// <summary>
  699. /// youTube events feed for friends activities
  700. /// </summary>
  701. public const string ActivityFeedUri = "https://gdata.youtube.com/feeds/api/events";
  702. private List<string> authors = new List<string>();
  703. /// <summary>
  704. /// base constructor
  705. /// </summary>
  706. public UserActivitiesQuery()
  707. : base(UserActivitiesQuery.ActivityFeedUri) {
  708. }
  709. /// <summary>holds the list of authors we want to search for</summary>
  710. public List<string> Authors {
  711. get { return this.authors; }
  712. set { this.authors = value; }
  713. }
  714. /// <summary>Creates the partial URI query string based on all
  715. /// set properties.</summary>
  716. /// <returns> string => the query part of the URI </returns>
  717. protected override string CalculateQuery(string basePath) {
  718. string path = base.CalculateQuery(basePath);
  719. StringBuilder newPath = new StringBuilder(path, 2048);
  720. char paramInsertion = InsertionParameter(path);
  721. string allAuthors = "";
  722. foreach (string s in this.authors) {
  723. if (allAuthors.Length > 0) {
  724. allAuthors += ",";
  725. }
  726. allAuthors += s;
  727. }
  728. paramInsertion = AppendQueryPart(allAuthors, "author", paramInsertion, newPath);
  729. return newPath.ToString();
  730. }
  731. }
  732. }