Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
Exposed the "found" field in search results and added a parameter to …
Browse files Browse the repository at this point in the history
…feed methods that lets you choose how many gfys come in each batch
  • Loading branch information
ObsidianMinor committed Apr 28, 2017
1 parent 367a04d commit df4c50a
Show file tree
Hide file tree
Showing 26 changed files with 305 additions and 138 deletions.
23 changes: 0 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,6 @@ Gfy completedGfy = await gfyStatus.GetGfyWhenCompleteAsync();
// congrats, you now have a gfy
```

### Feed guidelines
Gfycat.Net uses the magic power of IAsyncEnumerable from Rx.Net. Using its magic it's extremely easy to accidentally loop through a whole feed of gfys (there's a lot of gfys out there so it might take a while and will probably get you banned from using the API).
To prevent this, read feeds like this:
```csharp
IAsyncEnumerable<Gfy> gfySearchFeed = await client.SearchAsync("stop");
gfySearchFeed.Take(20).ForEach(gfy => ...);
```
or
```csharp
IFeed<Gfy> gfySearchFeed = await client.SearchAsync("stop");
foreach(Gfy gfy in gfySearchFeed.Content)
{
// do something
}
IFeed<Gfy> nextPageGfySearchFeed = await gfySearchFeed.GetNextPageAsync();
...
```
and not
```csharp
IAsyncEnumerable<Gfy> gfySearchFeed = await client.SearchAsync("stop");
gfySearchFeed.ForEach(gfy => ...);
```

### Using Analytics
[![NuGet version](https://badge.fury.io/nu/Gfycat.Net.Analytics.svg)](https://badge.fury.io/nu/Gfycat.Net.Analytics)

Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 1.0.8.{build}
version: 1.0.9.{build}
pull_requests:
do_not_increment_build_number: true
branches:
Expand Down
51 changes: 50 additions & 1 deletion docs/articles/intro.md
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
# @MarkusGordathian is working on this
# Intro
## Packages
There are two libraries in the Gfycat.Net project: Gfycat.Net and Gfycat.Net.Analytics.
* Gfycat.Net is the base library, it's the wrapper around the main API. You can read about the main API here: https://developers.gfycat.com/api
* Gfycat.Net.Analytics is the analytics wrapper. It wraps around the Gfycat analytics and impression API. You can read about the API here: https://developers.gfycat.com/analytics/

## Installing
Gfycat.Net has two package sources: NuGet and MyGet
* NuGet contains the official release packages. It's pushed to when AppVeyor builds from master branch. It's the version of the library which builds the docs.
* MyGet contains the developer release packages. It contains new features which are stable however not fully tested.

#### NuGet
The standard release can be installed like any other package. Go to the "Manage NuGet Packages" page for you project and searh for and install "Gfycat.Net". Gfycat.Net.Analytics can be install the same way.

#### MyGet
MyGet requires a bit more work, to get dev builds, you must add the MyGet feed as a package source in Visual Studio.

1. First, go to Tools -> Options -> NuGet Package Manager and select Package Sources.
2. Click the green plus button in the top right to add a new source
3. Near the bottom of the window, change the "Name" to something memorable, and change the "Source" to "https://www.myget.org/F/gfycat-net/api/v3/index.json"
4. Click OK, then open your project's packages window and change the "Source" dropdown to the package source name you defined before.
5. Search for Gfycat.Net like normal with "Include prereleases" checked

## Basics
#### GfycatClient
The GfycatClient contains all the main methods used get users, gfys, and feeds. It is constructed with either a GfycatClientConfig or a client ID and secret strings. You can get these on the [Gfycat developer site](https://developers.gfycat.com/signup).

With client ID and secret
```csharp
using Gfycat;
...
GfycatClient client = new GfycatClient("clientId", "clientSecret");
```

With client config
```csharp
using Gfycat;
...
GfycatClientConfig config = new GfycatClientConfig("clientId", "clientSecret");
// make changes to client's default values
GfycatClient client = new GfycatClient(config);
```

#### Authentication
All authentication falls under the method `AuthenticateAsync`. Depending on the provided parameters, different authentications are run. All method overloads and parameters are [documented here](https://obsidianminor.github.io/Gfycat.Net/api/Gfycat.GfycatClient.html#Gfycat_GfycatClient_AuthenticateAsync_Gfycat_RequestOptions_) and all authentication options explained on [the Gfycat docs](https://developers.gfycat.com/api/#authentication).

In the event you get a 401 (unauthorized) status code, by default the client will try to refresh the access token before retrying the request. If the refresh token is somehow null or invalid (by leaving the program running doing nothing for 6 months) or implicit browser authentication was used, the access token will not be refreshed and the request will fail. If you want to refresh the access token yourself, you can by calling `await RefreshTokenAsync()`. If you want to save the refresh token for later, you can use the property GfycatClient.RefreshToken to get the current refresh token. To reuse the token again, run `await RefreshTokenAsync(refreshToken)` using the saved token.

#### Feeds
Feeds in Gfycat.Net allow enumeration through large collections of items in batches. They are all defined by the interface IFeed<T> where T is the type of item in the feed. This can be a Gfy or another feed. IFeed<T> inherits IAsyncEnumerable<T> which means you can use LINQ on whole
54 changes: 36 additions & 18 deletions src/Gfycat.Net/API/GfycatApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,23 +247,23 @@ internal async Task<FollowersResponse> GetFollowersAsync(RequestOptions options)

#region User feeds

internal async Task<Feed> GetUserGfyFeedAsync(string userId, string cursor, RequestOptions options)
internal async Task<Feed> GetUserGfyFeedAsync(string userId, int count, string cursor, RequestOptions options)
{
string query = Utils.CreateQueryString(( "cursor", cursor ));
string query = Utils.CreateQueryString(("count", count), ( "cursor", cursor ));
RestResponse response = await SendAsync("GET", $"users/{userId}/gfycats{query}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Feed>(Config).ConfigureAwait(false);
}

internal async Task<Feed> GetCurrentUserGfyFeedAsync(string cursor, RequestOptions options)
internal async Task<Feed> GetCurrentUserGfyFeedAsync(int count, string cursor, RequestOptions options)
{
string query = Utils.CreateQueryString(("cursor",cursor));
string query = Utils.CreateQueryString(("count", count), ("cursor",cursor));
RestResponse response = await SendAsync("GET", $"me/gfycats{query}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Feed>(Config).ConfigureAwait(false);
}

internal async Task<Feed> GetFollowsGfyFeedAsync(string cursor, RequestOptions options)
internal async Task<Feed> GetFollowsGfyFeedAsync(int count, string cursor, RequestOptions options)
{
string query = Utils.CreateQueryString(( "cursor", cursor ));
string query = Utils.CreateQueryString(("count", count), ("cursor", cursor ));
RestResponse response = await SendAsync("GET", $"me/follows/gfycats{query}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Feed>(Config).ConfigureAwait(false);
}
Expand Down Expand Up @@ -644,9 +644,12 @@ internal async Task ShareGfyAsync(string gfyId, TwitterShareRequest shareParams,

#region Reaction gifs

internal async Task<TrendingTagsFeed> GetReactionGifsPopulatedAsync(ReactionLanguage lang, string cursor, RequestOptions options)
internal async Task<TrendingTagsFeed> GetReactionGifsPopulatedAsync(ReactionLanguage lang, int gfyCount, string cursor, RequestOptions options)
{
string query = Utils.CreateQueryString(("locale", Utils._reactionLangToString[lang]), ("cursor", cursor));
if (gfyCount <= GfycatClient.UseDefaultFeedCount)
gfyCount = Config.DefaultFeedItemCount;

string query = Utils.CreateQueryString(("locale", Utils._reactionLangToString[lang]), ("gfyCount", gfyCount), ("cursor", cursor));
RestResponse response = await SendAsync("GET", "reactions/populated" + query, options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<TrendingTagsFeed>(Config).ConfigureAwait(false);
}
Expand All @@ -655,9 +658,12 @@ internal async Task<TrendingTagsFeed> GetReactionGifsPopulatedAsync(ReactionLang

#region Trending feeds

internal async Task<TrendingFeed> GetTrendingFeedAsync(string tagName,string cursor, RequestOptions options)
internal async Task<TrendingFeed> GetTrendingFeedAsync(string tagName, int count, string cursor, RequestOptions options)
{
string queryString = Utils.CreateQueryString(("tagName", tagName), ("cursor", cursor));
if (count <= GfycatClient.UseDefaultFeedCount)
count = Config.DefaultFeedItemCount;

string queryString = Utils.CreateQueryString(("count", count), ("tagName", tagName), ("cursor", cursor));
RestResponse response = await SendAsync("GET", $"gfycats/trending{queryString}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<TrendingFeed>(Config).ConfigureAwait(false);
}
Expand All @@ -669,9 +675,15 @@ internal async Task<IEnumerable<string>> GetTrendingTagsAsync(string cursor, Req
return await response.ReadAsJsonAsync<IEnumerable<string>>(Config).ConfigureAwait(false);
}

internal async Task<TrendingTagsFeed> GetTrendingTagsPopulatedAsync(string cursor, RequestOptions options)
internal async Task<TrendingTagsFeed> GetTrendingTagsPopulatedAsync(string cursor, int tagCount, int gfyCount, RequestOptions options)
{
string queryString = Utils.CreateQueryString(("cursor", cursor));
if (gfyCount <= GfycatClient.UseDefaultFeedCount)
gfyCount = Config.DefaultFeedItemCount;

if (tagCount <= GfycatClient.UseDefaultFeedCount)
tagCount = Config.DefaultFeedItemCount;

string queryString = Utils.CreateQueryString(("tagCount", tagCount), ("gfyCount", gfyCount), ("cursor", cursor));
RestResponse response = await SendAsync("GET", $"tags/trending/populated{queryString}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<TrendingTagsFeed>(Config).ConfigureAwait(false);
}
Expand All @@ -680,18 +692,24 @@ internal async Task<TrendingTagsFeed> GetTrendingTagsPopulatedAsync(string curso

#region Search

internal async Task<Feed> SearchSiteAsync(string searchText, string cursor, RequestOptions options)
internal async Task<Models.SearchFeed> SearchSiteAsync(string searchText, int count, string cursor, RequestOptions options)
{
string queryString = Utils.CreateQueryString(("search_text", searchText), ("cursor", cursor));
if (count <= GfycatClient.UseDefaultFeedCount)
count = Config.DefaultFeedItemCount;

string queryString = Utils.CreateQueryString(("search_text", searchText), ("count", count), ("cursor", cursor));
RestResponse response = await SendAsync("GET", $"gfycats/search{queryString}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Feed>(Config).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Models.SearchFeed>(Config).ConfigureAwait(false);
}

internal async Task<Feed> SearchCurrentUserAsync(string searchText, string cursor, RequestOptions options)
internal async Task<Models.SearchFeed> SearchCurrentUserAsync(string searchText, int count, string cursor, RequestOptions options)
{
string queryString = Utils.CreateQueryString(("search_text", searchText), ("cursor", cursor));
if (count <= GfycatClient.UseDefaultFeedCount)
count = Config.DefaultFeedItemCount;

string queryString = Utils.CreateQueryString(("search_text", searchText), ("count", count), ("cursor", cursor));
RestResponse response = await SendAsync("GET", $"me/gfycats/search{queryString}", options).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Feed>(Config).ConfigureAwait(false);
return await response.ReadAsJsonAsync<Models.SearchFeed>(Config).ConfigureAwait(false);
}

#endregion
Expand Down
10 changes: 10 additions & 0 deletions src/Gfycat.Net/API/Models/SearchFeed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace Gfycat.API.Models
{
internal class SearchFeed : Feed
{
[JsonProperty("found")]
internal int Found { get; set; }
}
}
17 changes: 11 additions & 6 deletions src/Gfycat.Net/CurrentUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,21 +260,25 @@ public async Task<IEnumerable<User>> GetFollowersPopulatedAsync(RequestOptions o
/// <summary>
/// Gets the current user's private gfy feed
/// </summary>
/// <param name="count"></param>
/// <param name="options">The options for this request</param>
/// <returns></returns>
public async Task<GfyFeed> GetGfyFeedAsync(RequestOptions options = null)
public async Task<GfyFeed> GetGfyFeedAsync(int count = GfycatClient.UseDefaultFeedCount, RequestOptions options = null)
{
return CurrentUserGfyFeed.Create(Client, options, await Client.ApiClient.GetCurrentUserGfyFeedAsync(null, options).ConfigureAwait(false));
Utils.UseDefaultIfSpecified(ref count, Client.ApiClient.Config.DefaultFeedItemCount);
return CurrentUserGfyFeed.Create(Client, count, options, await Client.ApiClient.GetCurrentUserGfyFeedAsync(count, null, options).ConfigureAwait(false));
}

/// <summary>
/// Returns a timeline list of all published gfys in the users this user follows
/// </summary>
/// <param name="count"></param>
/// <param name="options">The options for this request</param>
/// <returns></returns>
public async Task<GfyFeed> GetTimelineFeedAsync(RequestOptions options = null)
public async Task<GfyFeed> GetTimelineFeedAsync(int count = GfycatClient.UseDefaultFeedCount, RequestOptions options = null)
{
return CurrentUserTimelineFeed.Create(Client, options, await Client.ApiClient.GetFollowsGfyFeedAsync(null, options).ConfigureAwait(false));
Utils.UseDefaultIfSpecified(ref count, Client.ApiClient.Config.DefaultFeedItemCount);
return CurrentUserTimelineFeed.Create(Client, count, options, await Client.ApiClient.GetFollowsGfyFeedAsync(count, null, options).ConfigureAwait(false));
}

#endregion
Expand Down Expand Up @@ -330,12 +334,13 @@ public async Task<IEnumerable<IAlbumInfo>> GetAlbumsAsync(RequestOptions options
/// <summary>
/// Searches the current user's gfys
/// </summary>
/// <param name="count"></param>
/// <param name="searchText"></param>
/// <param name="options">The options for this request</param>
/// <returns></returns>
public async Task<GfyFeed> SearchAsync(string searchText, RequestOptions options = null)
public async Task<SearchFeed> SearchAsync(string searchText, int count = GfycatClient.UseDefaultFeedCount, RequestOptions options = null)
{
return CurrentUserSearchFeed.Create(Client, await Client.ApiClient.SearchCurrentUserAsync(searchText, null, options).ConfigureAwait(false), searchText, options);
return CurrentUserSearchFeed.Create(Client, await Client.ApiClient.SearchCurrentUserAsync(searchText, count, null, options).ConfigureAwait(false), count, searchText, options);
}
/// <summary>
/// Adds a twitter provider to this account using the specified verifier and token
Expand Down
14 changes: 9 additions & 5 deletions src/Gfycat.Net/CurrentUserGfyFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Gfycat
{
internal class CurrentUserGfyFeed : GfyFeed
{
internal CurrentUserGfyFeed(GfycatClient client, RequestOptions defaultOptions) : base(client, defaultOptions)
internal CurrentUserGfyFeed(GfycatClient client, int count, RequestOptions defaultOptions) : base(client, count, defaultOptions)
{
}
/// <summary>
Expand All @@ -21,9 +21,9 @@ public override IAsyncEnumerator<Gfy> GetEnumerator()
return new FeedEnumerator<Gfy>(_client, this, _options);
}

internal static CurrentUserGfyFeed Create(GfycatClient client, RequestOptions options, Feed feed)
internal static CurrentUserGfyFeed Create(GfycatClient client, int count, RequestOptions options, Feed feed)
{
return new CurrentUserGfyFeed(client, options)
return new CurrentUserGfyFeed(client, count, options)
{
Content = feed.Gfycats.Select(g => Gfy.Create(client, g)).ToReadOnlyCollection(),
_cursor = feed.Cursor
Expand All @@ -32,11 +32,15 @@ internal static CurrentUserGfyFeed Create(GfycatClient client, RequestOptions op
/// <summary>
/// Returns the next page of this feed
/// </summary>
/// <param name="count"></param>
/// <param name="options"></param>
/// <returns></returns>
public async override Task<IFeed<Gfy>> GetNextPageAsync(RequestOptions options = null)
public async override Task<IFeed<Gfy>> GetNextPageAsync(int count = GfycatClient.UseDefaultFeedCount, RequestOptions options = null)
{
return Create(_client, options, await _client.ApiClient.GetCurrentUserGfyFeedAsync(_cursor, options).ConfigureAwait(false));
if (count <= GfycatClient.UseDefaultFeedCount)
count = _count;

return Create(_client, count, options, await _client.ApiClient.GetCurrentUserGfyFeedAsync(count, _cursor, options).ConfigureAwait(false));
}
}
}
25 changes: 12 additions & 13 deletions src/Gfycat.Net/CurrentUserSearchFeed.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Model = Gfycat.API.Models.Feed;
using Model = Gfycat.API.Models.SearchFeed;

namespace Gfycat
{
internal class CurrentUserSearchFeed : GfyFeed
internal class CurrentUserSearchFeed : SearchFeed
{
readonly string _searchText;

internal CurrentUserSearchFeed(GfycatClient client, string searchText, RequestOptions options) : base(client, options)
internal CurrentUserSearchFeed(GfycatClient client, int count, string searchText, RequestOptions options) : base(client, searchText, count, options)
{
_searchText = searchText;
}

internal static CurrentUserSearchFeed Create(GfycatClient client, Model model, string searchText, RequestOptions options)
internal static CurrentUserSearchFeed Create(GfycatClient client, Model model, int count, string searchText, RequestOptions options)
{
return new CurrentUserSearchFeed(client, searchText, options)
return new CurrentUserSearchFeed(client, count, searchText, options)
{
Content = model.Gfycats.Select(g => Gfy.Create(client, g)).ToReadOnlyCollection(),
_cursor = model.Cursor
_cursor = model.Cursor,
Count = model.Found
};
}
/// <summary>
Expand All @@ -34,11 +31,13 @@ public override IAsyncEnumerator<Gfy> GetEnumerator()
/// <summary>
/// Returns the next page of this feed
/// </summary>
/// <param name="count"></param>
/// <param name="options"></param>
/// <returns></returns>
public async override Task<IFeed<Gfy>> GetNextPageAsync(RequestOptions options = null)
public async override Task<IFeed<Gfy>> GetNextPageAsync(int count = GfycatClient.UseDefaultFeedCount, RequestOptions options = null)
{
return Create(_client, await _client.ApiClient.SearchCurrentUserAsync(_searchText, _cursor, options).ConfigureAwait(false), _searchText, options);
Utils.UseDefaultIfSpecified(ref count, _count);
return Create(_client, await _client.ApiClient.SearchCurrentUserAsync(SearchText, count, _cursor, options).ConfigureAwait(false), count, SearchText, options);
}
}
}
Loading

0 comments on commit df4c50a

Please sign in to comment.