diff --git a/.travis.yml b/.travis.yml
index 2b84fb67..ea0943ab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
language: csharp
-solution: InstagramAPI.sln
+solution: InstaSharper.sln
dotnet: 1.0.0-preview2-003121
sudo: required
os: linux
@@ -10,9 +10,9 @@ script:
- dotnet --info
# Run dotnet new
- dotnet restore
- - cd InstagramAPI
+ - cd InstaSharper
- dotnet --verbose build
- - cd ../InstagramAPI.Tests
+ - cd ../InstaSharper.Tests
- dotnet --verbose build
- - dotnet --verbose test
+ - dotnet --verbose test -parallel none
\ No newline at end of file
diff --git a/InstaSharper.Examples/App.config b/InstaSharper.Examples/App.config
new file mode 100644
index 00000000..51fffc74
--- /dev/null
+++ b/InstaSharper.Examples/App.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/InstaSharper.Examples/InstaSharper.Examples.csproj b/InstaSharper.Examples/InstaSharper.Examples.csproj
new file mode 100644
index 00000000..efe30f26
--- /dev/null
+++ b/InstaSharper.Examples/InstaSharper.Examples.csproj
@@ -0,0 +1,63 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {620D3DB5-5636-4A54-A7D7-600C6518C20E}
+ Exe
+ Properties
+ InstaSharper.Examples
+ InstaSharper.Examples
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\InstaSharper\bin\Debug\net452\InstaSharper.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/InstaSharper.Examples/InstaSharper.Examples.sln b/InstaSharper.Examples/InstaSharper.Examples.sln
new file mode 100644
index 00000000..fe06e8f5
--- /dev/null
+++ b/InstaSharper.Examples/InstaSharper.Examples.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstaSharper.Examples", "InstaSharper.Examples.csproj", "{620D3DB5-5636-4A54-A7D7-600C6518C20E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {620D3DB5-5636-4A54-A7D7-600C6518C20E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {620D3DB5-5636-4A54-A7D7-600C6518C20E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {620D3DB5-5636-4A54-A7D7-600C6518C20E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {620D3DB5-5636-4A54-A7D7-600C6518C20E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/InstaSharper.Examples/InstaSharperExamples.cs b/InstaSharper.Examples/InstaSharperExamples.cs
new file mode 100644
index 00000000..44b815fd
--- /dev/null
+++ b/InstaSharper.Examples/InstaSharperExamples.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Linq;
+using InstaSharper.API;
+using InstaSharper.API.Builder;
+using InstaSharper.Classes;
+
+namespace InstaSharper.Examples
+{
+ internal class InstaSharperExamples
+ {
+ private static IInstaApi _instaApi;
+
+ private static void Main(string[] args)
+ {
+ // create user session data and provide login details
+ var userSession = new UserSessionData
+ {
+ UserName = "username",
+ Password = "password"
+ };
+ // create new InstaApi instance using Builder
+ _instaApi = new InstaApiBuilder()
+ .SetUser(userSession)
+ .Build();
+ // login
+ var logInResult = _instaApi.Login();
+ if (!logInResult.Succeeded) { Console.WriteLine($"Unable to login: {logInResult.Message}"); }
+ else
+ {
+ // get currently logged in user
+ var currentUser = _instaApi.GetCurrentUser().Value;
+ Console.WriteLine($"Logged in: username - {currentUser.UserName}, full name - {currentUser.FullName}");
+ // get followers
+ var followers = _instaApi.GetUserFollowersAsync(currentUser.UserName, 5).Result.Value;
+ Console.WriteLine($"Count of followers [{currentUser.UserName}]:{followers.Count}");
+ // get user's media
+ var currentUserMedia = _instaApi.GetUserMedia(currentUser.UserName, 5);
+ if (currentUserMedia.Succeeded)
+ {
+ Console.WriteLine($"Media count [{currentUser.UserName}]: {currentUserMedia.Value.Count}");
+ foreach (var media in currentUserMedia.Value) Console.WriteLine($"Media [{currentUser.UserName}]: {media.Caption.Text}, {media.Code}, likes: {media.LikesCount}, image link: {media.Images.LastOrDefault()?.Url}");
+ }
+
+ //get user feed, first 5 pages
+ var userFeed = _instaApi.GetUserFeed(5);
+ if (userFeed.Succeeded)
+ {
+ Console.WriteLine($"Feed items (in {userFeed.Value.Pages} pages) [{currentUser.UserName}]: {userFeed.Value.Items.Count}");
+ foreach (var media in userFeed.Value.Items) Console.WriteLine($"Feed item - code:{media.Code}, likes: {media.LikesCount}");
+ }
+ // get tag feed, first 5 pages
+ var tagFeed = _instaApi.GetTagFeed("gm", 5);
+ if (userFeed.Succeeded)
+ {
+ Console.WriteLine($"Tag feed items (in {tagFeed.Value.Pages} pages) [{currentUser.UserName}]: {tagFeed.Value.Count}");
+ foreach (var media in tagFeed.Value) Console.WriteLine($"Tag feed item - code: {media.Code}, likes: {media.LikesCount}");
+ }
+ var logoutResult = _instaApi.Logout();
+ if (logoutResult.Value) Console.WriteLine("Logout succeed");
+ }
+ Console.ReadKey();
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper.Examples/Properties/AssemblyInfo.cs b/InstaSharper.Examples/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..b094a7c8
--- /dev/null
+++ b/InstaSharper.Examples/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("InstaSharper.Examples")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("InstaSharper.Examples")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("620d3db5-5636-4a54-a7d7-600c6518c20e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/InstagramAPI.Tests/InstagramAPI.Tests.xproj b/InstaSharper.Tests/InstaSharper.Tests.xproj
similarity index 95%
rename from InstagramAPI.Tests/InstagramAPI.Tests.xproj
rename to InstaSharper.Tests/InstaSharper.Tests.xproj
index 9e8dbfaf..042194cb 100644
--- a/InstagramAPI.Tests/InstagramAPI.Tests.xproj
+++ b/InstaSharper.Tests/InstaSharper.Tests.xproj
@@ -7,7 +7,7 @@
dbe6fbb7-cde7-4cdf-ab08-989a43cc4d46
- InstagramAPI.Tests
+ InstaSharper.Tests
.\obj
.\bin\
v4.5.2
diff --git a/InstagramAPI.Tests/Properties/AssemblyInfo.cs b/InstaSharper.Tests/Properties/AssemblyInfo.cs
similarity index 85%
rename from InstagramAPI.Tests/Properties/AssemblyInfo.cs
rename to InstaSharper.Tests/Properties/AssemblyInfo.cs
index def343ae..6ce07dda 100644
--- a/InstagramAPI.Tests/Properties/AssemblyInfo.cs
+++ b/InstaSharper.Tests/Properties/AssemblyInfo.cs
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.InteropServices;
+using Xunit;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -7,8 +8,10 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("InstagramApi.Tests")]
+[assembly: AssemblyProduct("InstaSharper.Tests")]
[assembly: AssemblyTrademark("")]
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
+
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
diff --git a/InstagramAPI.Tests/Tests/ApiInstanceBuilderTest.cs b/InstaSharper.Tests/Tests/ApiInstanceBuilderTest.cs
similarity index 68%
rename from InstagramAPI.Tests/Tests/ApiInstanceBuilderTest.cs
rename to InstaSharper.Tests/Tests/ApiInstanceBuilderTest.cs
index 74f9f3fa..82e45152 100644
--- a/InstagramAPI.Tests/Tests/ApiInstanceBuilderTest.cs
+++ b/InstaSharper.Tests/Tests/ApiInstanceBuilderTest.cs
@@ -1,9 +1,10 @@
-using InstagramAPI.API.Builder;
-using InstagramAPI.Tests.Utils;
+using InstaSharper.API.Builder;
+using InstaSharper.Tests.Utils;
using Xunit;
-namespace InstagramAPI.Tests.Tests
+namespace InstaSharper.Tests.Tests
{
+ [Collection("InstaSharper Tests")]
public class ApiInstanceBuilderTest
{
[Fact]
diff --git a/InstagramAPI.Tests/Tests/LoginTest.cs b/InstaSharper.Tests/Tests/AuthTest.cs
similarity index 56%
rename from InstagramAPI.Tests/Tests/LoginTest.cs
rename to InstaSharper.Tests/Tests/AuthTest.cs
index 12bf81f5..a631a4a1 100644
--- a/InstagramAPI.Tests/Tests/LoginTest.cs
+++ b/InstaSharper.Tests/Tests/AuthTest.cs
@@ -1,36 +1,34 @@
using System;
-using InstagramAPI.Classes;
-using InstagramAPI.Tests.Utils;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
using Xunit;
using Xunit.Abstractions;
-namespace InstagramAPI.Tests.Tests
+namespace InstaSharper.Tests.Tests
{
- public class LoginTest
+ [Collection("InstaSharper Tests")]
+ public class AuthTest
{
- public LoginTest(ITestOutputHelper output)
+ public AuthTest(ITestOutputHelper output)
{
- this.output = output;
+ _output = output;
}
- private readonly ITestOutputHelper output;
+ private readonly ITestOutputHelper _output;
[Fact]
public async void UserLoginFailTest()
{
- //arrange
var username = "alex_codegarage";
var password = "boombaby!";
var apiInstance =
- TestHelpers.GetDefaultInstaApiInstance(new UserCredentials
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
{
UserName = username,
Password = password
});
- output.WriteLine("Got API instance");
- //act
+ _output.WriteLine("Got API instance");
var loginResult = await apiInstance.LoginAsync();
- //assert
Assert.False(loginResult.Succeeded);
Assert.False(apiInstance.IsUserAuthenticated);
}
@@ -38,19 +36,16 @@ public async void UserLoginFailTest()
[Fact]
public async void UserLoginSuccessTest()
{
- //arrange
var username = "alex_codegarage";
var password = Environment.GetEnvironmentVariable("instaapiuserpassword");
- var apiInstance =
- TestHelpers.GetDefaultInstaApiInstance(new UserCredentials
- {
- UserName = username,
- Password = password
- });
- output.WriteLine("Got API instance");
- //act
+ var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = username,
+ Password = password
+ });
+ Assert.False(apiInstance.IsUserAuthenticated);
+
var loginResult = await apiInstance.LoginAsync();
- //assert
Assert.True(loginResult.Succeeded);
Assert.True(apiInstance.IsUserAuthenticated);
}
diff --git a/InstaSharper.Tests/Tests/DiscoverTest.cs b/InstaSharper.Tests/Tests/DiscoverTest.cs
new file mode 100644
index 00000000..c9c3acd0
--- /dev/null
+++ b/InstaSharper.Tests/Tests/DiscoverTest.cs
@@ -0,0 +1,40 @@
+using System;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace InstaSharper.Tests.Tests
+{
+ [Collection("InstaSharper Tests")]
+ public class DiscoverTest
+ {
+ public DiscoverTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ private readonly ITestOutputHelper _output;
+ private readonly string _username = "alex_codegarage";
+ private readonly string _password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+
+ [Fact]
+ public async void ExploreTest()
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var result = await apiInstance.GetExploreFeedAsync(0);
+ var exploreGeed = result.Value;
+ //assert
+ Assert.True(result.Succeeded);
+ Assert.NotNull(exploreGeed);
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper.Tests/Tests/FeedTest.cs b/InstaSharper.Tests/Tests/FeedTest.cs
new file mode 100644
index 00000000..b0dc4588
--- /dev/null
+++ b/InstaSharper.Tests/Tests/FeedTest.cs
@@ -0,0 +1,82 @@
+using System;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace InstaSharper.Tests.Tests
+{
+ [Collection("InstaSharper Tests")]
+ public class FeedTest
+ {
+ public FeedTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ private readonly ITestOutputHelper _output;
+ private readonly string _username = "alex_codegarage";
+ private readonly string _password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+
+ [Theory]
+ [InlineData("christmas")]
+ [InlineData("rock")]
+ public async void GetTagFeedTest(string tag)
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var result = await apiInstance.GetTagFeedAsync(tag);
+ var tagFeed = result.Value;
+ //assert
+ Assert.True(result.Succeeded);
+ Assert.NotNull(tagFeed);
+ }
+
+
+ [Theory]
+ [InlineData("rock")]
+ public async void GetUserTagFeedTest(string username)
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var result = await apiInstance.GetUserTagsAsync(username, 5);
+ var tagFeed = result.Value;
+ //assert
+ Assert.True(result.Succeeded);
+ Assert.NotNull(tagFeed);
+ }
+
+ [Fact]
+ public async void GetUserFeedTest()
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var getFeedResult = await apiInstance.GetUserFeedAsync(5);
+ var feed = getFeedResult.Value;
+ //assert
+ Assert.True(getFeedResult.Succeeded);
+ Assert.NotNull(feed);
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper.Tests/Tests/FollowersTest.cs b/InstaSharper.Tests/Tests/FollowersTest.cs
new file mode 100644
index 00000000..679000a7
--- /dev/null
+++ b/InstaSharper.Tests/Tests/FollowersTest.cs
@@ -0,0 +1,57 @@
+using System;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace InstaSharper.Tests.Tests
+{
+ [Collection("InstaSharper Tests")]
+ public class FollowersTest
+ {
+ public FollowersTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ private readonly ITestOutputHelper _output;
+
+ [Theory]
+ [InlineData("discovery")]
+ public async void GetUserFollowersTest(string username)
+ {
+ var currentUsername = "alex_codegarage";
+ var password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+ var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = currentUsername,
+ Password = password
+ });
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var result = await apiInstance.GetUserFollowersAsync(username, 10);
+ var followers = result.Value;
+ //assert
+ Assert.True(result.Succeeded);
+ Assert.NotNull(followers);
+ }
+
+ [Fact]
+ public async void GetCurrentUserFollwersTest()
+ {
+ var username = "alex_codegarage";
+ var password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+ var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = username,
+ Password = password
+ });
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var result = await apiInstance.GetCurrentUserFollowersAsync();
+ var followers = result.Value;
+ //assert
+ Assert.True(result.Succeeded);
+ Assert.NotNull(followers);
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper.Tests/Tests/MediaTest.cs b/InstaSharper.Tests/Tests/MediaTest.cs
new file mode 100644
index 00000000..ea791835
--- /dev/null
+++ b/InstaSharper.Tests/Tests/MediaTest.cs
@@ -0,0 +1,67 @@
+using System;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace InstaSharper.Tests.Tests
+{
+ [Collection("InstaSharper Tests")]
+ public class MediaTest
+ {
+ private readonly ITestOutputHelper _output;
+
+ public MediaTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ [Theory]
+ [InlineData("1379932752706850783")]
+ public async void GetMediaByCodeTest(string mediaId)
+ {
+ //arrange
+ var username = "alex_codegarage";
+ var password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+ var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = username,
+ Password = password
+ });
+ //act
+ _output.WriteLine($"Trying to login as user: {username}");
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ _output.WriteLine($"Getting media by ID: {mediaId}");
+ var media = await apiInstance.GetMediaByCodeAsync(mediaId);
+ //assert
+ Assert.NotNull(media);
+ }
+
+ [Theory]
+ [InlineData("alex_codegarage")]
+ [InlineData("instagram")]
+ [InlineData("therock")]
+ public async void GetUserMediaListTest(string userToFetch)
+ {
+ //arrange
+ var username = "alex_codegarage";
+ var password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+ var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = username,
+ Password = password
+ });
+ var random = new Random(DateTime.Today.Millisecond);
+ var pages = random.Next(1, 10);
+ //act
+ _output.WriteLine($"Trying to login as user: {username}");
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ _output.WriteLine($"Getting posts of user: {userToFetch}");
+
+ var posts = await apiInstance.GetUserMediaAsync(userToFetch, pages);
+ //assert
+ Assert.NotNull(posts);
+ Assert.Equal(userToFetch, posts.Value[random.Next(0, posts.Value.Count)].User.UserName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper.Tests/Tests/UserInfoTest.cs b/InstaSharper.Tests/Tests/UserInfoTest.cs
new file mode 100644
index 00000000..c5ee9869
--- /dev/null
+++ b/InstaSharper.Tests/Tests/UserInfoTest.cs
@@ -0,0 +1,61 @@
+using System;
+using InstaSharper.Classes;
+using InstaSharper.Tests.Utils;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace InstaSharper.Tests.Tests
+{
+ [Collection("InstaSharper Tests")]
+ public class UserInfoTest
+ {
+ public UserInfoTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ private readonly ITestOutputHelper _output;
+ private readonly string _username = "alex_codegarage";
+ private readonly string _password = Environment.GetEnvironmentVariable("instaapiuserpassword");
+
+ [Fact]
+ public async void GetCurrentUserTest()
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var getUserResult = await apiInstance.GetCurrentUserAsync();
+ var user = getUserResult.Value;
+ //assert
+ Assert.True(getUserResult.Succeeded);
+ Assert.NotNull(user);
+ Assert.Equal(user.UserName, _username);
+ }
+
+ [Fact]
+ public async void GetUserTest()
+ {
+ //arrange
+ var apiInstance =
+ TestHelpers.GetDefaultInstaApiInstance(new UserSessionData
+ {
+ UserName = _username,
+ Password = _password
+ });
+ //act
+ if (!TestHelpers.Login(apiInstance, _output)) return;
+ var getUserResult = await apiInstance.GetUserAsync(_username);
+ var user = getUserResult.Value;
+ //assert
+ Assert.True(getUserResult.Succeeded);
+ Assert.NotNull(user);
+ Assert.Equal(user.UserName, _username);
+ }
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI.Tests/Utils/TestHelpers.cs b/InstaSharper.Tests/Utils/TestHelpers.cs
similarity index 66%
rename from InstagramAPI.Tests/Utils/TestHelpers.cs
rename to InstaSharper.Tests/Utils/TestHelpers.cs
index 3bcfdd61..e38f6448 100644
--- a/InstagramAPI.Tests/Utils/TestHelpers.cs
+++ b/InstaSharper.Tests/Utils/TestHelpers.cs
@@ -1,10 +1,9 @@
-using System.Threading.Tasks;
-using InstagramAPI.API;
-using InstagramAPI.API.Builder;
-using InstagramAPI.Classes;
+using InstaSharper.API;
+using InstaSharper.API.Builder;
+using InstaSharper.Classes;
using Xunit.Abstractions;
-namespace InstagramAPI.Tests.Utils
+namespace InstaSharper.Tests.Utils
{
public class TestHelpers
{
@@ -17,7 +16,7 @@ public static IInstaApi GetDefaultInstaApiInstance(string username)
return apiInstance;
}
- public static IInstaApi GetDefaultInstaApiInstance(UserCredentials user)
+ public static IInstaApi GetDefaultInstaApiInstance(UserSessionData user)
{
var apiInstance = new InstaApiBuilder()
.SetUser(user)
@@ -26,9 +25,9 @@ public static IInstaApi GetDefaultInstaApiInstance(UserCredentials user)
return apiInstance;
}
- public static async Task Login(IInstaApi apiInstance, ITestOutputHelper output)
+ public static bool Login(IInstaApi apiInstance, ITestOutputHelper output)
{
- var loginResult = await apiInstance.LoginAsync();
+ var loginResult = apiInstance.Login();
if (!loginResult.Succeeded)
{
output.WriteLine($"Can't login: {loginResult.Message}");
diff --git a/InstagramAPI.Tests/Utils/TestLogger.cs b/InstaSharper.Tests/Utils/TestLogger.cs
similarity index 65%
rename from InstagramAPI.Tests/Utils/TestLogger.cs
rename to InstaSharper.Tests/Utils/TestLogger.cs
index bd2cba31..89c8fa92 100644
--- a/InstagramAPI.Tests/Utils/TestLogger.cs
+++ b/InstaSharper.Tests/Utils/TestLogger.cs
@@ -1,6 +1,6 @@
-using InstagramAPI.Logger;
+using InstaSharper.Logger;
-namespace InstagramAPI.Tests.Utils
+namespace InstaSharper.Tests.Utils
{
internal class TestLogger : ILogger
{
diff --git a/InstagramAPI.Tests/project.json b/InstaSharper.Tests/project.json
similarity index 92%
rename from InstagramAPI.Tests/project.json
rename to InstaSharper.Tests/project.json
index 9722838a..abf9906b 100644
--- a/InstagramAPI.Tests/project.json
+++ b/InstaSharper.Tests/project.json
@@ -3,7 +3,7 @@
"testRunner": "xunit",
"dependencies": {
"xunit": "2.2.0-beta2-build3300",
- "InstagramAPI": "1.2.0",
+ "InstaSharper": "1.2.1",
"dotnet-test-xunit": "2.2.0-preview2-build1029"
},
"frameworks": {
diff --git a/InstagramAPI.sln b/InstaSharper.sln
similarity index 82%
rename from InstagramAPI.sln
rename to InstaSharper.sln
index c2aaeab9..bd2eb111 100644
--- a/InstagramAPI.sln
+++ b/InstaSharper.sln
@@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstagramAPI", "InstagramAPI\InstagramAPI.xproj", "{449A948D-CC65-4D1A-8159-6FA232F972D9}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstaSharper", "InstaSharper\InstaSharper.xproj", "{449A948D-CC65-4D1A-8159-6FA232F972D9}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstagramAPI.Tests", "InstagramAPI.Tests\InstagramAPI.Tests.xproj", "{DBE6FBB7-CDE7-4CDF-AB08-989A43CC4D46}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstaSharper.Tests", "InstaSharper.Tests\InstaSharper.Tests.xproj", "{DBE6FBB7-CDE7-4CDF-AB08-989A43CC4D46}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/InstagramAPI/API/Builder/IInstaApiBuilder.cs b/InstaSharper/API/Builder/IInstaApiBuilder.cs
similarity index 70%
rename from InstagramAPI/API/Builder/IInstaApiBuilder.cs
rename to InstaSharper/API/Builder/IInstaApiBuilder.cs
index 1bf3ff99..8f0b7f00 100644
--- a/InstagramAPI/API/Builder/IInstaApiBuilder.cs
+++ b/InstaSharper/API/Builder/IInstaApiBuilder.cs
@@ -1,8 +1,8 @@
using System.Net.Http;
-using InstagramAPI.Classes;
-using InstagramAPI.Logger;
+using InstaSharper.Classes;
+using InstaSharper.Logger;
-namespace InstagramAPI.API.Builder
+namespace InstaSharper.API.Builder
{
public interface IInstaApiBuilder
{
@@ -11,6 +11,6 @@ public interface IInstaApiBuilder
IInstaApiBuilder UseHttpClient(HttpClient httpClient);
IInstaApiBuilder UseHttpClientHandler(HttpClientHandler handler);
IInstaApiBuilder SetUserName(string username);
- IInstaApiBuilder SetUser(UserCredentials user);
+ IInstaApiBuilder SetUser(UserSessionData user);
}
}
\ No newline at end of file
diff --git a/InstagramAPI/API/Builder/InstaApiBuilder.cs b/InstaSharper/API/Builder/InstaApiBuilder.cs
similarity index 87%
rename from InstagramAPI/API/Builder/InstaApiBuilder.cs
rename to InstaSharper/API/Builder/InstaApiBuilder.cs
index 955f9bae..d260db4b 100644
--- a/InstagramAPI/API/Builder/InstaApiBuilder.cs
+++ b/InstaSharper/API/Builder/InstaApiBuilder.cs
@@ -1,10 +1,10 @@
using System;
using System.Net.Http;
-using InstagramAPI.Classes;
-using InstagramAPI.Classes.Android.DeviceInfo;
-using InstagramAPI.Logger;
+using InstaSharper.Classes;
+using InstaSharper.Classes.Android.DeviceInfo;
+using InstaSharper.Logger;
-namespace InstagramAPI.API.Builder
+namespace InstaSharper.API.Builder
{
public class InstaApiBuilder : IInstaApiBuilder
{
@@ -12,7 +12,7 @@ public class InstaApiBuilder : IInstaApiBuilder
private HttpClientHandler _httpHandler = new HttpClientHandler();
private ILogger _logger;
private ApiRequestMessage _requestMessage;
- private UserCredentials _user;
+ private UserSessionData _user;
public IInstaApi Build()
{
@@ -59,11 +59,11 @@ public IInstaApiBuilder UseHttpClientHandler(HttpClientHandler handler)
public IInstaApiBuilder SetUserName(string username)
{
- _user = new UserCredentials {UserName = username};
+ _user = new UserSessionData {UserName = username};
return this;
}
- public IInstaApiBuilder SetUser(UserCredentials user)
+ public IInstaApiBuilder SetUser(UserSessionData user)
{
_user = user;
return this;
diff --git a/InstaSharper/API/IInstaApi.cs b/InstaSharper/API/IInstaApi.cs
new file mode 100644
index 00000000..e31e28b6
--- /dev/null
+++ b/InstaSharper/API/IInstaApi.cs
@@ -0,0 +1,54 @@
+using System.Threading.Tasks;
+using InstaSharper.Classes;
+using InstaSharper.Classes.Models;
+
+namespace InstaSharper.API
+{
+ public interface IInstaApi
+ {
+ #region Properties
+
+ bool IsUserAuthenticated { get; }
+
+ #endregion
+
+ #region Sync Members
+
+ IResult GetUser(string username);
+ Task> GetUserAsync(string username);
+ IResult GetUserMedia(string username, int maxPages = 0);
+ Task> GetUserMediaAsync(string username, int maxPages = 0);
+ IResult GetMediaByCode(string postCode);
+ Task> GetMediaByCodeAsync(string postCode);
+ IResult Login();
+ IResult Logout();
+
+ IResult GetCurrentUser();
+ IResult GetCurentUserFollowers(int maxPages = 0);
+ IResult GetUserFollowers(string username, int maxPages = 0);
+
+ IResult GetTagFeed(string tag, int maxPages = 0);
+
+ IResult GetExploreFeed(int maxPages = 0);
+ IResult GetUserTags(string username, int maxPages = 0);
+
+ #endregion
+
+ #region Async Members
+
+ Task> LoginAsync();
+ Task> LogoutAsync();
+ IResult GetUserFeed(int maxPages = 0);
+ Task> GetUserFeedAsync(int maxPages = 0);
+ Task> GetCurrentUserAsync();
+
+ Task> GetTagFeedAsync(string tag, int maxPages = 0);
+ Task> GetUserFollowersAsync(string username, int maxPages = 0);
+ Task> GetCurrentUserFollowersAsync(int maxPages = 0);
+
+ Task> GetExploreFeedAsync(int maxPages = 0);
+ Task> GetUserTagsAsync(string username, int maxPages = 0);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper/API/InstaApi.cs b/InstaSharper/API/InstaApi.cs
new file mode 100644
index 00000000..ac1b7f0d
--- /dev/null
+++ b/InstaSharper/API/InstaApi.cs
@@ -0,0 +1,584 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using InstaSharper.Classes;
+using InstaSharper.Classes.Android.DeviceInfo;
+using InstaSharper.Classes.Models;
+using InstaSharper.Converters;
+using InstaSharper.Converters.Json;
+using InstaSharper.Helpers;
+using InstaSharper.Logger;
+using InstaSharper.ResponseWrappers;
+using InstaSharper.ResponseWrappers.BaseResponse;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace InstaSharper.API
+{
+ public class InstaApi : IInstaApi
+ {
+ private readonly AndroidDevice _deviceInfo;
+ private readonly HttpClient _httpClient;
+ private readonly HttpClientHandler _httpHandler;
+ private readonly ILogger _logger;
+ private readonly ApiRequestMessage _requestMessage;
+ private readonly UserSessionData _user;
+
+ public InstaApi(UserSessionData user,
+ ILogger logger,
+ HttpClient httpClient,
+ HttpClientHandler httpHandler,
+ ApiRequestMessage requestMessage,
+ AndroidDevice deviceInfo)
+ {
+ _user = user;
+ _logger = logger;
+ _httpClient = httpClient;
+ _httpHandler = httpHandler;
+ _requestMessage = requestMessage;
+ _deviceInfo = deviceInfo;
+ }
+
+ public bool IsUserAuthenticated { get; private set; }
+
+ #region sync part
+
+ public IResult GetMediaByCode(string postCode)
+ {
+ return GetMediaByCodeAsync(postCode).Result;
+ }
+
+ public IResult GetUser(string username)
+ {
+ return GetUserAsync(username).Result;
+ }
+
+ public IResult GetUserFeed(int maxPages = 0)
+ {
+ return GetUserFeedAsync(maxPages).Result;
+ }
+
+ public IResult GetUserMedia(string username, int maxPages = 0)
+ {
+ return GetUserMediaAsync(username, maxPages).Result;
+ }
+
+ public IResult Login()
+ {
+ return LoginAsync().Result;
+ }
+
+ public IResult Logout()
+ {
+ return LogoutAsync().Result;
+ }
+
+ public IResult GetUserFollowers(string username, int maxPages = 0)
+ {
+ return GetUserFollowersAsync(username, maxPages).Result;
+ }
+
+ public IResult GetTagFeed(string tag, int maxPages = 0)
+ {
+ return GetTagFeedAsync(tag, maxPages).Result;
+ }
+
+ public IResult GetExploreFeed(int maxPages = 0)
+ {
+ return GetExploreFeedAsync(maxPages).Result;
+ }
+
+ public IResult GetUserTags(string username, int maxPages = 0)
+ {
+ return GetUserTagsAsync(username, maxPages).Result;
+ }
+
+ public IResult GetCurentUserFollowers(int maxPages = 0)
+ {
+ return GetCurrentUserFollowersAsync(maxPages).Result;
+ }
+
+ #endregion
+
+ #region async part
+
+ public async Task> GetMediaByCodeAsync(string postCode)
+ {
+ ValidateUser();
+ var mediaUri = UriCreator.GetMediaUri(postCode);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, mediaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var mediaResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ if (mediaResponse.Medias?.Count != 1)
+ {
+ string errorMessage = $"Got wrong media count for request with media id={postCode}";
+ _logger.Write(errorMessage);
+ return Result.Fail(errorMessage);
+ }
+ var converter = ConvertersFabric.GetSingleMediaConverter(mediaResponse.Medias.FirstOrDefault());
+ return Result.Success(converter.Convert());
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaMedia)null);
+ }
+
+ public async Task> GetUserAsync(string username)
+ {
+ ValidateUser();
+ var userUri = UriCreator.GetUserUri(username);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userUri, _deviceInfo);
+ request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_TIMEZONE, InstaApiConstants.TIMEZONE_OFFSET.ToString()));
+ request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_COUNT, "1"));
+ request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_RANK_TOKEN, _user.RankToken));
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var userInfo = JsonConvert.DeserializeObject(json);
+ var user = userInfo.Users?.FirstOrDefault(u => u.UserName == username);
+ if (user == null)
+ {
+ string errorMessage = $"Can't find this user: {username}";
+ _logger.Write(errorMessage);
+ return Result.Fail(errorMessage);
+ }
+ var converter = ConvertersFabric.GetUserConverter(user);
+ return Result.Success(converter.Convert());
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaUser)null);
+ }
+
+ public IResult GetCurrentUser()
+ {
+ return GetCurrentUserAsync().Result;
+ }
+
+ public async Task> GetCurrentUserAsync()
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ var instaUri = UriCreator.GetCurrentUserUri();
+ dynamic jsonObject = new JObject();
+ jsonObject._uuid = _deviceInfo.DeviceGuid;
+ jsonObject._uid = _user.LoggedInUder.Pk;
+ jsonObject._csrftoken = _user.CsrfToken;
+ var fields = new Dictionary
+ {
+ {"_uuid", _deviceInfo.DeviceGuid.ToString()},
+ {"_uid", _user.LoggedInUder.Pk},
+ {"_csrftoken", _user.CsrfToken}
+ };
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
+ request.Content = new FormUrlEncodedContent(fields);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var user = JsonConvert.DeserializeObject(json);
+ var converter = ConvertersFabric.GetUserConverter(user.User);
+ var userConverted = converter.Convert();
+
+ return Result.Success(userConverted);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaUser)null);
+ }
+
+ public async Task> GetUserFeedAsync(int maxPages = 0)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ var userFeedUri = UriCreator.GetUserFeedUri();
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userFeedUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ var feed = new InstaFeed();
+ if (response.StatusCode != HttpStatusCode.OK) return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaFeed)null);
+ var feedResponse = JsonConvert.DeserializeObject(json, new InstaFeedResponseDataConverter());
+ var converter = ConvertersFabric.GetFeedConverter(feedResponse);
+ var feedConverted = converter.Convert();
+ feed.Medias.AddRange(feedConverted.Medias);
+ var nextId = feedResponse.NextMaxId;
+ while (feedResponse.MoreAvailable && (feed.Pages < maxPages))
+ {
+ if (string.IsNullOrEmpty(nextId)) break;
+ var nextFeed = await GetUserFeedWithMaxIdAsync(nextId);
+ if (!nextFeed.Succeeded) Result.Success($"Not all pages was downloaded: {nextFeed.Message}", feed);
+ nextId = nextFeed.Value.NextMaxId;
+ feed.Medias.AddRange(nextFeed.Value.Items.Select(ConvertersFabric.GetSingleMediaConverter).Select(conv => conv.Convert()));
+ feed.Pages++;
+ }
+ return Result.Success(feed);
+ }
+
+ public async Task> GetCurrentUserFollowersAsync(int maxPages = 0)
+ {
+ ValidateUser();
+ return await GetUserFollowersAsync(_user.UserName, maxPages);
+ }
+
+ public async Task> GetExploreFeedAsync(int maxPages = 0)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ try
+ {
+ if (maxPages == 0) maxPages = int.MaxValue;
+ var exploreUri = UriCreator.GetExploreUri();
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, exploreUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ var exploreFeed = new InstaFeed();
+ if (response.StatusCode != HttpStatusCode.OK) return Result.Fail("", (InstaFeed)null);
+ var mediaResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ exploreFeed.Medias.AddRange(mediaResponse.Medias.Select(ConvertersFabric.GetSingleMediaConverter).Select(converter => converter.Convert()));
+ exploreFeed.Stories.AddRange(mediaResponse.Stories.Select(ConvertersFabric.GetSingleStoryConverter).Select(converter => converter.Convert()));
+ var pages = 1;
+ var nextId = mediaResponse.NextMaxId;
+ while (!string.IsNullOrEmpty(nextId) && (pages < maxPages)) if (string.IsNullOrEmpty(nextId) || (nextId == "0")) break;
+ return Result.Success(exploreFeed);
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, (InstaFeed)null);
+ }
+ }
+
+ public async Task> GetUserTagsAsync(string username, int maxPages = 0)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ try
+ {
+ if (maxPages == 0) maxPages = int.MaxValue;
+ var user = await GetUserAsync(username);
+ if (!user.Succeeded || string.IsNullOrEmpty(user.Value.Pk)) return Result.Fail($"Unable to get user {username}", (InstaMediaList)null);
+ var uri = UriCreator.GetUserTagsUri(user.Value?.Pk, _user.RankToken);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, uri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ var userTags = new InstaMediaList();
+ if (response.StatusCode != HttpStatusCode.OK) return Result.Fail("", (InstaMediaList)null);
+ var mediaResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ var nextId = mediaResponse.NextMaxId;
+ userTags.AddRange(mediaResponse.Medias.Select(ConvertersFabric.GetSingleMediaConverter).Select(converter => converter.Convert()));
+ var pages = 1;
+ while (!string.IsNullOrEmpty(nextId) && (pages < maxPages))
+ {
+ uri = UriCreator.GetUserTagsUri(user.Value?.Pk, _user.RankToken, nextId);
+ var nextMedia = await GetUserMediaListWithMaxIdAsync(uri);
+ if (!nextMedia.Succeeded) Result.Success($"Not all pages was downloaded: {nextMedia.Message}", userTags);
+ nextId = nextMedia.Value.NextMaxId;
+ userTags.AddRange(mediaResponse.Medias.Select(ConvertersFabric.GetSingleMediaConverter).Select(converter => converter.Convert()));
+ pages++;
+ }
+ return Result.Success(userTags);
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, (InstaMediaList)null);
+ }
+ }
+
+ public async Task> GetUserFollowersAsync(string username, int maxPages = 0)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ try
+ {
+ if (maxPages == 0) maxPages = int.MaxValue;
+ var user = await GetUserAsync(username);
+ var userFeedUri = UriCreator.GetUserFollowersUri(user.Value.Pk, _user.RankToken);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userFeedUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ var followers = new InstaUserList();
+ if (response.StatusCode != HttpStatusCode.OK) return Result.Fail("", (InstaUserList)null);
+ var followersResponse = JsonConvert.DeserializeObject(json);
+ if (!followersResponse.IsOK()) Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaUserList)null);
+ followers.AddRange(followersResponse.Items.Select(ConvertersFabric.GetUserConverter).Select(converter => converter.Convert()));
+ if (!followersResponse.IsBigList) return Result.Success(followers);
+ var pages = 1;
+ while (!string.IsNullOrEmpty(followersResponse.NextMaxId) && (pages < maxPages))
+ {
+ var nextFollowers = Result.Success(followersResponse);
+ nextFollowers = await GetUserFollowersWithMaxIdAsync(username, nextFollowers.Value.NextMaxId);
+ if (!nextFollowers.Succeeded) Result.Success($"Not all pages was downloaded: {nextFollowers.Message}", followers);
+ followers.AddRange(nextFollowers.Value.Items.Select(ConvertersFabric.GetUserConverter).Select(converter => converter.Convert()));
+ pages++;
+ }
+ return Result.Success(followers);
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, (InstaUserList)null);
+ }
+ }
+
+ private async Task> GetUserFollowersWithMaxIdAsync(string username, string maxId)
+ {
+ ValidateUser();
+ try
+ {
+ if (!IsUserAuthenticated) throw new ArgumentException("user must be authenticated");
+ var user = await GetUserAsync(username);
+ var userFeedUri = UriCreator.GetUserFollowersUri(user.Value.Pk, _user.RankToken, maxId);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userFeedUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var followersResponse = JsonConvert.DeserializeObject(json);
+ if (!followersResponse.IsOK()) Result.Fail("", (InstaFollowersResponse)null);
+ return Result.Success(followersResponse);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaFollowersResponse)null);
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, (InstaFollowersResponse)null);
+ }
+ }
+
+ public async Task> CheckpointAsync(string checkPointUrl)
+ {
+ if (string.IsNullOrEmpty(checkPointUrl)) return Result.Fail("Empty checkpoint URL", false);
+ var instaUri = new Uri(checkPointUrl);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK) return Result.Success(true);
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, false);
+ }
+
+ public async Task> GetTagFeedAsync(string tag, int maxPages = 0)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ var userFeedUri = UriCreator.GetTagFeedUri(tag);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userFeedUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var feedResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ var converter = ConvertersFabric.GetMediaListConverter(feedResponse);
+ var tagFeed = new InstaFeed();
+ tagFeed.Medias.AddRange(converter.Convert());
+ var nextId = feedResponse.NextMaxId;
+ while (feedResponse.MoreAvailable && (tagFeed.Pages < maxPages))
+ {
+ var nextMedia = await GetTagFeedWithMaxIdAsync(tag, nextId);
+ if (!nextMedia.Succeeded) Result.Success($"Not all pages was downloaded: {nextMedia.Message}", tagFeed);
+ nextId = nextMedia.Value.NextMaxId;
+ converter = ConvertersFabric.GetMediaListConverter(nextMedia.Value);
+ tagFeed.Medias.AddRange(converter.Convert());
+ tagFeed.Pages++;
+ }
+ return Result.Success(tagFeed);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaFeed)null);
+ }
+
+ private async Task> GetTagFeedWithMaxIdAsync(string tag, string nextId)
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ try
+ {
+ var instaUri = UriCreator.GetTagFeedUri(tag);
+ instaUri = new UriBuilder(instaUri) { Query = $"max_id={nextId}" }.Uri;
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var feedResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ return Result.Success(feedResponse);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaMediaListResponse)null);
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, (InstaMediaListResponse)null);
+ }
+ }
+
+ public async Task> GetUserMediaAsync(string username, int maxPages = 0)
+ {
+ ValidateUser();
+ if (maxPages == 0) maxPages = int.MaxValue;
+ var user = GetUser(username).Value;
+ var instaUri = UriCreator.GetUserMediaListUri(user.Pk);
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var mediaResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ var converter = ConvertersFabric.GetMediaListConverter(mediaResponse);
+ var mediaList = converter.Convert();
+ var nextId = mediaResponse.NextMaxId;
+ while (mediaResponse.MoreAvailable && (mediaList.Pages < maxPages))
+ {
+ instaUri = UriCreator.GetMediaListWithMaxIdUri(user.Pk, nextId);
+ var nextMedia = await GetUserMediaListWithMaxIdAsync(instaUri);
+ if (!nextMedia.Succeeded) Result.Success($"Not all pages was downloaded: {nextMedia.Message}", mediaList);
+ nextId = nextMedia.Value.NextMaxId;
+ mediaList.AddRange(converter.Convert());
+ mediaList.Pages++;
+ }
+ return Result.Success(mediaList);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaMediaList)null);
+ }
+
+
+ public async Task> LoginAsync()
+ {
+ ValidateUser();
+ ValidateRequestMessage();
+ try
+ {
+ var csrftoken = string.Empty;
+ var firstResponse = await _httpClient.GetAsync(_httpClient.BaseAddress);
+ var cookies = _httpHandler.CookieContainer.GetCookies(_httpClient.BaseAddress);
+ foreach (Cookie cookie in cookies) if (cookie.Name == InstaApiConstants.CSRFTOKEN) csrftoken = cookie.Value;
+ _user.CsrfToken = csrftoken;
+ var instaUri = UriCreator.GetLoginUri();
+ var signature = $"{_requestMessage.GenerateSignature()}.{_requestMessage.GetMessageString()}";
+ var fields = new Dictionary
+ {
+ {InstaApiConstants.HEADER_IG_SIGNATURE, signature},
+ {InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION}
+ };
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
+ request.Content = new FormUrlEncodedContent(fields);
+ request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
+ request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var loginInfo =
+ JsonConvert.DeserializeObject(json);
+ IsUserAuthenticated = (loginInfo.User != null) && (loginInfo.User.UserName == _user.UserName);
+ var converter = ConvertersFabric.GetUserConverter(loginInfo.User);
+ _user.LoggedInUder = converter.Convert();
+ _user.RankToken = $"{_user.LoggedInUder.Pk}_{_requestMessage.phone_id}";
+ return Result.Success(true);
+ }
+ else
+ {
+ var loginInfo = GetBadStatusFromJsonString(json);
+ if (loginInfo.ErrorType == "checkpoint_logged_out")
+ {
+ var checkPointResult = await CheckpointAsync(loginInfo.CheckPointUrl);
+ IsUserAuthenticated = checkPointResult.Succeeded;
+ return Result.Success(checkPointResult.Value);
+ }
+ return Result.Fail(loginInfo.Message, false);
+ }
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, false);
+ }
+ }
+
+ public async Task> LogoutAsync()
+ {
+ ValidateUser();
+ ValidateLoggedIn();
+ try
+ {
+ var instaUri = UriCreator.GetLogoutUri();
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var logoutInfo = JsonConvert.DeserializeObject(json);
+ IsUserAuthenticated = logoutInfo.Status == "ok";
+ return Result.Success(true);
+ }
+ else
+ {
+ var logoutInfo = GetBadStatusFromJsonString(json);
+ return Result.Fail(logoutInfo.Message, false);
+ }
+ }
+ catch (Exception exception)
+ {
+ return Result.Fail(exception.Message, false);
+ }
+ }
+
+ #endregion
+
+ #region private part
+
+ private void ValidateUser()
+ {
+ if (string.IsNullOrEmpty(_user.UserName) || string.IsNullOrEmpty(_user.Password)) throw new ArgumentException("user name and password must be specified");
+ }
+
+ private void ValidateLoggedIn()
+ {
+ if (!IsUserAuthenticated) throw new ArgumentException("user must be authenticated");
+ }
+
+ private void ValidateRequestMessage()
+ {
+ if ((_requestMessage == null) || _requestMessage.IsEmpty()) throw new ArgumentException("API request message null or empty");
+ }
+
+ private BadStatusResponse GetBadStatusFromJsonString(string json)
+ {
+ var badStatus = new BadStatusResponse();
+ try { badStatus = JsonConvert.DeserializeObject(json); }
+ catch (Exception ex)
+ {
+ badStatus.Message = ex.Message;
+ }
+ return badStatus;
+ }
+
+ private async Task> GetUserFeedWithMaxIdAsync(string maxId)
+ {
+ Uri instaUri;
+ if (!Uri.TryCreate(new Uri(InstaApiConstants.INSTAGRAM_URL), InstaApiConstants.TIMELINEFEED, out instaUri)) throw new Exception("Cant create search user URI");
+ var userUriBuilder = new UriBuilder(instaUri) { Query = $"max_id={maxId}" };
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, userUriBuilder.Uri, _deviceInfo);
+ request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_PHONE_ID, _requestMessage.phone_id));
+ request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_TIMEZONE, InstaApiConstants.TIMEZONE_OFFSET.ToString()));
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var feedResponse = JsonConvert.DeserializeObject(json, new InstaFeedResponseDataConverter());
+ return Result.Success(feedResponse);
+ }
+ return Result.Fail(GetBadStatusFromJsonString(json).Message, (InstaFeedResponse)null);
+ }
+
+ private async Task> GetUserMediaListWithMaxIdAsync(Uri instaUri)
+ {
+ var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
+ var response = await _httpClient.SendAsync(request);
+ var json = await response.Content.ReadAsStringAsync();
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var mediaResponse = JsonConvert.DeserializeObject(json, new InstaMediaListDataConverter());
+ return Result.Success(mediaResponse);
+ }
+ return Result.Fail("", (InstaMediaListResponse)null);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI/API/InstaApiConstants.cs b/InstaSharper/API/InstaApiConstants.cs
similarity index 72%
rename from InstagramAPI/API/InstaApiConstants.cs
rename to InstaSharper/API/InstaApiConstants.cs
index 5ec2a3c6..e4efd530 100644
--- a/InstagramAPI/API/InstaApiConstants.cs
+++ b/InstaSharper/API/InstaApiConstants.cs
@@ -1,7 +1,8 @@
-namespace InstagramAPI.API
+namespace InstaSharper.API
{
- public static class InstaApiConstants
+ internal static class InstaApiConstants
{
+ public const string CURRENTUSER = API_SUFFIX + "/v1/accounts/current_user?edit=true";
public const string MAX_MEDIA_ID_POSTFIX = "/media/?max_id=";
public const string HEADER_MAX_ID = "max_id";
public const string MEDIA = "/media/";
@@ -14,29 +15,32 @@ public static class InstaApiConstants
public const string HEADER_XML_HTTP_REQUEST = "XMLHttpRequest";
public const string INSTAGRAM_URL = "https://i.instagram.com";
public const string API_SUFFIX = "/api";
- public const string GET_USER = API_SUFFIX + "/v1/accounts/login/";
public const string SEARCH_USERS = API_SUFFIX + "/v1/users/search";
public const string ACCOUNTS_LOGIN = API_SUFFIX + "/v1/accounts/login/";
- public const string TIMELINEFEED = API_SUFFIX + "/v1/feed/timeline/";
+ public const string ACCOUNTS_LOGOUT = API_SUFFIX + "/v1/accounts/logout/";
+ public const string EXPLORE = API_SUFFIX + "/v1/discover/explore/";
+ public const string TIMELINEFEED = API_SUFFIX + "/v1/feed/timeline";
public const string USEREFEED = API_SUFFIX + "/v1/feed/user/";
+ public const string GET_USER_TAGS = API_SUFFIX + "/v1/usertags/{0}/feed/";
public const string GET_MEDIA = API_SUFFIX + "/v1/media/{0}/info/";
-
+ public const string GET_USER_FOLLOWERS = API_SUFFIX + "/v1/friendships/{0}/followers/?rank_token={1}";
+ public const string GET_TAG_FEED = API_SUFFIX + "/v1/feed/tag/{0}";
public const string HEADER_USER_AGENT = "User-Agent";
- public const string USER_AGENT = "Instagram 8.0.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)";
+ public const string USER_AGENT = "Instagram 9.7.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)";
public const string HEADER_QUERY = "q";
public const string HEADER_RANK_TOKEN = "rank_token";
public const string HEADER_COUNT = "count";
- public const string IG_SIGNATURE_KEY = "9b3b9e55988c954e51477da115c58ae82dcae7ac01c735b4443a3c5923cb593a";
+ public const string IG_SIGNATURE_KEY = "2f6dcdf76deb0d3fd008886d032162a79b88052b5f50538c1ee93c4fe7d02e60";
public const string HEADER_IG_SIGNATURE = "signed_body";
public const string IG_SIGNATURE_KEY_VERSION = "4";
public const string HEADER_IG_SIGNATURE_KEY_VERSION = "ig_sig_key_version";
- public const string IG_CAPABILITIES = "3Q==";
+ public const string IG_CAPABILITIES = "3Ro=";
public const string HEADER_IG_CAPABILITIES = "X-IG-Capabilities";
public const string IG_CONNECTION_TYPE = "WIFI";
public const string HEADER_IG_CONNECTION_TYPE = "X-IG-Connection-Type";
- public const string ACCEPT_LANGUAGE = "en-NZ";
+ public const string ACCEPT_LANGUAGE = "en-US";
public const string HEADER_ACCEPT_LANGUAGE = "Accept-Language";
public const string ACCEPT_ENCODING = "gzip, deflate, sdch";
public const string HEADER_ACCEPT_ENCODING = "gzip, deflate, sdch";
diff --git a/InstagramAPI/Classes/Android/DeviceInfo/AndroidDevice.cs b/InstaSharper/Classes/Android/DeviceInfo/AndroidDevice.cs
similarity index 94%
rename from InstagramAPI/Classes/Android/DeviceInfo/AndroidDevice.cs
rename to InstaSharper/Classes/Android/DeviceInfo/AndroidDevice.cs
index c9b59e8f..f9e76ce1 100644
--- a/InstagramAPI/Classes/Android/DeviceInfo/AndroidDevice.cs
+++ b/InstaSharper/Classes/Android/DeviceInfo/AndroidDevice.cs
@@ -1,6 +1,6 @@
using System;
-namespace InstagramAPI.Classes.Android.DeviceInfo
+namespace InstaSharper.Classes.Android.DeviceInfo
{
public class AndroidDevice
{
diff --git a/InstagramAPI/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs b/InstaSharper/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs
similarity index 99%
rename from InstagramAPI/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs
rename to InstaSharper/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs
index d6ab237c..cbb50c8b 100644
--- a/InstagramAPI/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs
+++ b/InstaSharper/Classes/Android/DeviceInfo/AndroidDeviceGenerator.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace InstagramAPI.Classes.Android.DeviceInfo
+namespace InstaSharper.Classes.Android.DeviceInfo
{
public class AndroidDeviceGenerator
{
diff --git a/InstagramAPI/Classes/Android/DeviceInfo/ApiRequestMessage.cs b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs
similarity index 91%
rename from InstagramAPI/Classes/Android/DeviceInfo/ApiRequestMessage.cs
rename to InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs
index d9c4ba72..fb8b0c07 100644
--- a/InstagramAPI/Classes/Android/DeviceInfo/ApiRequestMessage.cs
+++ b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs
@@ -1,9 +1,9 @@
using System;
-using InstagramAPI.API;
-using InstagramAPI.Helpers;
+using InstaSharper.API;
+using InstaSharper.Helpers;
using Newtonsoft.Json;
-namespace InstagramAPI.Classes.Android.DeviceInfo
+namespace InstaSharper.Classes.Android.DeviceInfo
{
public class ApiRequestMessage
{
diff --git a/InstagramAPI/Classes/Android/LoginInfoAndroid.cs b/InstaSharper/Classes/Android/LoginInfoAndroid.cs
similarity index 53%
rename from InstagramAPI/Classes/Android/LoginInfoAndroid.cs
rename to InstaSharper/Classes/Android/LoginInfoAndroid.cs
index 737dd938..0d02205c 100644
--- a/InstagramAPI/Classes/Android/LoginInfoAndroid.cs
+++ b/InstaSharper/Classes/Android/LoginInfoAndroid.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Android
+namespace InstaSharper.Classes.Android
{
public class LoginInfoAndroid
{
diff --git a/InstagramAPI/Classes/IResult.cs b/InstaSharper/Classes/IResult.cs
similarity index 80%
rename from InstagramAPI/Classes/IResult.cs
rename to InstaSharper/Classes/IResult.cs
index eeb8af9a..e31a3bdd 100644
--- a/InstagramAPI/Classes/IResult.cs
+++ b/InstaSharper/Classes/IResult.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes
+namespace InstaSharper.Classes
{
public interface IResult
{
diff --git a/InstaSharper/Classes/Models/CheckPointType.cs b/InstaSharper/Classes/Models/CheckPointType.cs
new file mode 100644
index 00000000..9df708ce
--- /dev/null
+++ b/InstaSharper/Classes/Models/CheckPointType.cs
@@ -0,0 +1,7 @@
+namespace InstaSharper.Classes.Models
+{
+ public enum CheckPointType
+ {
+ CheckpointLoggedOut = 0
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/Dimensions.cs b/InstaSharper/Classes/Models/Dimensions.cs
similarity index 75%
rename from InstagramAPI/Classes/Models/Dimensions.cs
rename to InstaSharper/Classes/Models/Dimensions.cs
index ef9d3838..cc1baffc 100644
--- a/InstagramAPI/Classes/Models/Dimensions.cs
+++ b/InstaSharper/Classes/Models/Dimensions.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class Dimensions
{
diff --git a/InstagramAPI/Classes/Models/Image.cs b/InstaSharper/Classes/Models/Image.cs
similarity index 88%
rename from InstagramAPI/Classes/Models/Image.cs
rename to InstaSharper/Classes/Models/Image.cs
index 1c421f6a..4ff173fd 100644
--- a/InstagramAPI/Classes/Models/Image.cs
+++ b/InstaSharper/Classes/Models/Image.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class Image
{
diff --git a/InstagramAPI/Classes/Models/Images.cs b/InstaSharper/Classes/Models/Images.cs
similarity index 82%
rename from InstagramAPI/Classes/Models/Images.cs
rename to InstaSharper/Classes/Models/Images.cs
index fb775956..9bb22e44 100644
--- a/InstagramAPI/Classes/Models/Images.cs
+++ b/InstaSharper/Classes/Models/Images.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class Images
{
diff --git a/InstagramAPI/Classes/Models/InstaCaption.cs b/InstaSharper/Classes/Models/InstaCaption.cs
similarity index 90%
rename from InstagramAPI/Classes/Models/InstaCaption.cs
rename to InstaSharper/Classes/Models/InstaCaption.cs
index c3fd59bc..6975e8b5 100644
--- a/InstagramAPI/Classes/Models/InstaCaption.cs
+++ b/InstaSharper/Classes/Models/InstaCaption.cs
@@ -1,6 +1,6 @@
using System;
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaCaption
{
diff --git a/InstaSharper/Classes/Models/InstaFeed.cs b/InstaSharper/Classes/Models/InstaFeed.cs
new file mode 100644
index 00000000..180ef4f9
--- /dev/null
+++ b/InstaSharper/Classes/Models/InstaFeed.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace InstaSharper.Classes.Models
+{
+ public class InstaFeed
+ {
+ public int MediaItemsCount => Medias.Count;
+ public int StoriesItemsCount => Stories.Count;
+
+ public List Medias { get; set; } = new List();
+ public List Stories { get; set; } = new List();
+
+ public int Pages { get; set; } = 1;
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/InstaFriendshipStatus.cs b/InstaSharper/Classes/Models/InstaFriendshipStatus.cs
similarity index 85%
rename from InstagramAPI/Classes/Models/InstaFriendshipStatus.cs
rename to InstaSharper/Classes/Models/InstaFriendshipStatus.cs
index f30dcd16..afad47fc 100644
--- a/InstagramAPI/Classes/Models/InstaFriendshipStatus.cs
+++ b/InstaSharper/Classes/Models/InstaFriendshipStatus.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaFriendshipStatus
{
diff --git a/InstagramAPI/Classes/Models/InstaLocation.cs b/InstaSharper/Classes/Models/InstaLocation.cs
similarity index 67%
rename from InstagramAPI/Classes/Models/InstaLocation.cs
rename to InstaSharper/Classes/Models/InstaLocation.cs
index edf27f8e..df10dde8 100644
--- a/InstagramAPI/Classes/Models/InstaLocation.cs
+++ b/InstaSharper/Classes/Models/InstaLocation.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaLocation
{
diff --git a/InstagramAPI/Classes/Models/InstaMedia.cs b/InstaSharper/Classes/Models/InstaMedia.cs
similarity index 84%
rename from InstagramAPI/Classes/Models/InstaMedia.cs
rename to InstaSharper/Classes/Models/InstaMedia.cs
index c168e7fc..5ec85af7 100644
--- a/InstagramAPI/Classes/Models/InstaMedia.cs
+++ b/InstaSharper/Classes/Models/InstaMedia.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaMedia
{
@@ -46,5 +46,9 @@ public class InstaMedia
public bool PhotoOfYou { get; set; }
public bool HasLiked { get; set; }
+
+ public List Tags { get; set; } = new List();
+
+ public InstaUserList Likers { get; set; } = new InstaUserList();
}
}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/InstaMediaList.cs b/InstaSharper/Classes/Models/InstaMediaList.cs
similarity index 55%
rename from InstagramAPI/Classes/Models/InstaMediaList.cs
rename to InstaSharper/Classes/Models/InstaMediaList.cs
index e01b8dc0..fe026ac2 100644
--- a/InstagramAPI/Classes/Models/InstaMediaList.cs
+++ b/InstaSharper/Classes/Models/InstaMediaList.cs
@@ -1,9 +1,9 @@
using System.Collections.Generic;
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaMediaList : List
{
- public int Pages { get; set; }
+ public int Pages { get; set; } = -1;
}
}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/InstaMediaType.cs b/InstaSharper/Classes/Models/InstaMediaType.cs
similarity index 66%
rename from InstagramAPI/Classes/Models/InstaMediaType.cs
rename to InstaSharper/Classes/Models/InstaMediaType.cs
index 517fd1af..21437613 100644
--- a/InstagramAPI/Classes/Models/InstaMediaType.cs
+++ b/InstaSharper/Classes/Models/InstaMediaType.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public enum InstaMediaType
{
diff --git a/InstaSharper/Classes/Models/InstaPosition.cs b/InstaSharper/Classes/Models/InstaPosition.cs
new file mode 100644
index 00000000..cfaf062a
--- /dev/null
+++ b/InstaSharper/Classes/Models/InstaPosition.cs
@@ -0,0 +1,14 @@
+namespace InstaSharper.Classes.Models
+{
+ public class InstaPosition
+ {
+ public InstaPosition(double x, double y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ public double X { get; set; }
+ public double Y { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/InstaSharper/Classes/Models/InstaStory.cs b/InstaSharper/Classes/Models/InstaStory.cs
new file mode 100644
index 00000000..73476248
--- /dev/null
+++ b/InstaSharper/Classes/Models/InstaStory.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace InstaSharper.Classes.Models
+{
+ public class InstaStory
+ {
+ public bool CanReply { get; set; }
+
+ public DateTime ExpiringAt { get; set; }
+
+ public InstaUser User { get; set; }
+
+ public string SourceToken { get; set; }
+
+ public bool Seen { get; set; }
+
+ public string LatestReelMedia { get; set; }
+
+ public string Id { get; set; }
+
+ public int RankedPosition { get; set; }
+
+ public int SeenRankedPosition { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/InstaUser.cs b/InstaSharper/Classes/Models/InstaUser.cs
similarity index 83%
rename from InstagramAPI/Classes/Models/InstaUser.cs
rename to InstaSharper/Classes/Models/InstaUser.cs
index 6506a129..7d41819b 100644
--- a/InstagramAPI/Classes/Models/InstaUser.cs
+++ b/InstaSharper/Classes/Models/InstaUser.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaUser
{
@@ -25,6 +25,6 @@ public class InstaUser
public string Pk { get; set; }
public string MutualFollowersCount { get; set; }
- public static InstaUser Empty => new InstaUser { FullName = string.Empty, UserName = string.Empty };
+ public static InstaUser Empty => new InstaUser {FullName = string.Empty, UserName = string.Empty};
}
}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/InstaUserList.cs b/InstaSharper/Classes/Models/InstaUserList.cs
similarity index 72%
rename from InstagramAPI/Classes/Models/InstaUserList.cs
rename to InstaSharper/Classes/Models/InstaUserList.cs
index 7c1a87ba..7709edd4 100644
--- a/InstagramAPI/Classes/Models/InstaUserList.cs
+++ b/InstaSharper/Classes/Models/InstaUserList.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class InstaUserList : List
{
diff --git a/InstaSharper/Classes/Models/InstaUserTag.cs b/InstaSharper/Classes/Models/InstaUserTag.cs
new file mode 100644
index 00000000..8f04d1cb
--- /dev/null
+++ b/InstaSharper/Classes/Models/InstaUserTag.cs
@@ -0,0 +1,11 @@
+namespace InstaSharper.Classes.Models
+{
+ public class InstaUserTag
+ {
+ public InstaPosition Position { get; set; }
+
+ public string TimeInVideo { get; set; }
+
+ public InstaUser User { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/InstagramAPI/Classes/Models/Likes.cs b/InstaSharper/Classes/Models/Likes.cs
similarity index 77%
rename from InstagramAPI/Classes/Models/Likes.cs
rename to InstaSharper/Classes/Models/Likes.cs
index 22db287c..6df7e061 100644
--- a/InstagramAPI/Classes/Models/Likes.cs
+++ b/InstaSharper/Classes/Models/Likes.cs
@@ -1,4 +1,4 @@
-namespace InstagramAPI.Classes.Models
+namespace InstaSharper.Classes.Models
{
public class Likes
{
diff --git a/InstagramAPI/Classes/Result.cs b/InstaSharper/Classes/Result.cs
similarity index 90%
rename from InstagramAPI/Classes/Result.cs
rename to InstaSharper/Classes/Result.cs
index 4943137e..a6bf6109 100644
--- a/InstagramAPI/Classes/Result.cs
+++ b/InstaSharper/Classes/Result.cs
@@ -1,12 +1,15 @@
using System;
-namespace InstagramAPI.Classes
+namespace InstaSharper.Classes
{
public static class Result
{
public static IResult Success(T resValue)
=> new Result(true, string.Empty, resValue);
+ public static IResult Success(string successMsg, T resValue)
+ => new Result(true, successMsg, resValue);
+
public static IResult